OmniAICreator/Qiita-1.07M huggingface dataset:
Docekr　基礎知識①

## はじめに
急な依頼が舞い込んだ。今までリリース検証しかしていなかった新人君は環境構築を任された。
ゴールはいつも行うリリース検証を新しい環境で行うこと。
タイムリミットは3週間。今回はDockerfileについてアウトプットしていく。

## Dockerと仮想化技術の違い
__仮想化技術__ ：物理的なマシンを仮想的に用意している。
CPU、メモリなどの物理的な部品をソフトウェアで補っていて、OSは何を入れてもOK。

__Docker__：OS（Linux）機能の一部を持ったもので、足りない他の機能を物理的なホストマシンのOSの機能に頼っている。頼っている物理的なマシンにもLinuxが必要で、コンテナにもLinuxが必要。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2609668/911d3170-94ad-d14c-0468-60a08b724d2a.png)

## Dockerとは？
　Dockerとは、Docker社（旧dotCloud）が開発するコンテナのアプリケーション実行環境を管理するオープンソースソフトウェア（OSS)
　実行環境を他のプロセスから隔離し、その中でアプリケーションを動作させる技術。コンテナが利用するリソースは他のプロセスやコンテナから隔離されている。そのため、コンテナに構築されたアプリは独立したコンピュータでアプリが動作しているように見える。よく、 __コンテナ型仮想化技術__ と言われる。
　コンテナを用いることで、異なるサーバでも、同じ構成の環境を簡単に構築することができる。
　　⇒ __各コンテナホストOSのカーネルを利用しているという点__

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2609668/8aadd03a-eda1-cb4b-e225-ebd32d9d2cca.png)


### Dockerのメリット
__・開発ライフサイクルの改善に強い__
__・開発環境が簡単に用意でき、かつ本番環境と共通化できる__
⇒開発環境と本番環境が同じのため運用コストも下がる
__・アプリケーション実行環境を高速にデプロイできる__
__・リソースの消費が少ない__

### Dockerのデメリット
__・Linux環境でしか動かない__
__・完全な分離ではない__
⇒ハードウェアをエミュレーションしているわけではない
　それぞれのコンテナのCPU利用率やメモリー消費量を制限し、ほかのコンテナに影響を与えない仕組みがあるが完璧じゃない

### Dockerの全体の流れ
①DockerHubなどのレジストリからイメージをPullする
②DockerfileでPullしたイメージをもとに設計図を作成する
③DockerComposeでDockerfileをビルドしてコンテナ起動する
「作る」→「起動する」→「停止する」→「破棄する」→「作る」....

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2609668/9fffea33-deaa-7842-d3ec-64eb8246dfb2.png)

## Dockerコンテナとは？
Dockerコンテナとは、Dockerエンジンのの上で動いている仮想環境のこと。
Dockerコンテナには、OSからミドルウェア、アプリケーションまで、様々な環境を作ることができる。
そして、このコンテナは「ホストOSのカーネル=Linuxカーネルを利用して動いている」という特徴がある。



## Docker Desktopとは？
[Docker Desktop](https://www.docker.com/products/docker-desktop/)とはインストールが簡単なアプリケーションであり、コンテナ化したアプリケーションとマイクロサービスの構築と共有が簡単になる。

__主な機能__
・あらゆるクラウド・プラットフォーム上で、あらゆる言語やフレームワークを用いる、あらゆるアプリケーションのコンテナ化と共有を可能にする
・簡単なインストールで、完全な Docker 開発環境をセットアップする
・Kubernetes の最新バージョンを含む
・自動更新によって、最新版かつ安全性を保つ
・Windows では、アプリケーション構築のために Linux と Windows Server 環境を相互に切り替え可能
・Windows マシン上の WSL 2 を通し、Linux 上でネイティブに動作する能力
・サポートしている統合開発環境を用い、コンテナ内での開発やデバッグ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2609668/8fedf203-ab92-9534-c076-d0002f92054a.png)

## DockerHubとは？
[Docker Hub](https://hub.docker.com/)はDocker imageを管理するレジストリ。
レジストリには「パブリックリポジトリ」と「プライベートリポジトリ」が存在する。
ちなみにレジストリはDockerHub以外にもAWSやGCP、Azureといったパブリッククラウド上にも存在しているので使い分けが可能である。

※DockerHubは、GitHubやBitbucketと連携ができる。連携すると、GitリポジトリにDockerfileをコミットした時に、自動的にdocker buildしたものをDockerHubに登録ができる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2609668/37b03584-69ff-c144-29d1-0bf27153d509.png)



## 用語集
__・エミュレーション__：ある装置やソフトウェア、システムの挙動を別のソフトウェアなどによって模倣し、代替として動作させること
__・コンテナ__：Docker上で動作するアプリケーションの単位
__・レジストリ__：Dockerイメージの貯蔵庫。
__・Docker Engine__：コンテナ化及びコンテナを動作させるためのアプリケーション
　　　　　　　　　Dockerの核となる部分
__・Dockerfile__：Docker imageをビルドするための手順が記載されたファイル
__・DockerHub__：Dockerイメージの貯蔵庫
__・Docker image（イメージ）__：コンテナを作成するための依存関係や情報を含むデータ
　　　　　　　　　　　　　　     コンテナはこのイメージが元になって作成される
Android 通知が表示されない問題

テストがてらに主に公式リファレンスの内容を参考に通知表示を実装してみました。
https://developer.android.com/training/notify-user/build-notification

```kotlin
        val notificationId = 123
        val notificationManager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager

        val name = "name"
        val descriptionText = "description"
        val channel = NotificationChannel("test", name, NotificationManager.IMPORTANCE_HIGH).apply {
            description = descriptionText
        }
        notificationManager.createNotificationChannel(channel)

        val notification = NotificationCompat.Builder(this, "CHANNEL_ID")
            .setContentTitle("title")
            .setContentText("text")
            .setSmallIcon(R.drawable.ic_launcher_foreground)
            .setPriority(NotificationCompat.PRIORITY_DEFAULT)
            .build()

        notificationManager.notify(notificationId, notification)
```

上の実装だと通知が表示されませんでした。何が原因なのかある程度悩んで分かったのはテスト用に適当に設定していたNotificationChannelの第一引数の値("test")と、NotificationCompat.Builderの第二引数の値("CHANNEL_ID")が一致していないからでした。

```kotlin
        val notificationId = 123
        val channelId = "CHANNEL_ID" // これの話
        val notificationManager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager

        val name = "name"
        val descriptionText = "description"
        val channel = NotificationChannel(channelId, name, NotificationManager.IMPORTANCE_HIGH).apply {
            description = descriptionText
        }
        notificationManager.createNotificationChannel(channel)

        val notification = NotificationCompat.Builder(this, channelId)
            .setContentTitle("title")
            .setContentText("text")
            .setSmallIcon(R.drawable.ic_launcher_foreground)
            .setPriority(NotificationCompat.PRIORITY_DEFAULT)
            .build()

        notificationManager.notify(notificationId, notification)
```

■テスト環境
Pixel 5a (Android12)
result = true && false && false || trueで少しハマった

```javascript
const result = true && false && false || true // false
```
2番目の条件でfalseになると思っていた。


ですが結果は**true**です。

考え方は
「true && false && false」 or 「true」
になるので、そりゃtrueになるよなと思った。

いやはや無駄な時間を使ってしまった。。。
バックオリフィス ってなに？

## 勉強前イメージ

バックドア的な？

## 調査

### バックオリフィス とは

クラッキングツールの一つで、
Cult of the Dead Cow と呼ばれるハッカーブループが配布している有名なリモートアクセスツールになります。
バックオリフィスはwindowsマシンを制御するソフトでサーバとクライアントに分かれている。
クライアントの部分は、ユーザ宛のメールに添付ファイルなどで送られて実行するとプログラムが実行されてシステムが内部にインストールされます。
ネットを通じてサーバと接続し、リモートアクセスが可能になってしまいます。

バックオリフィスと同じようなクラッキングツールは他にも
SubSeven や NetBus などがあります。

バックオリフィスはフリーでインターネット上で配布されていたので
スクリプトキディの蔓延に繋がりました。
※スクリプトキディとは専門知識がなく、配布されている攻撃ツールを使って使用するクラッカーのこと

基本的な対策はアンチウイルスソフトを使用することになります。

## 勉強後イメージ

結構いろんな攻撃方法見てても、
ウイルスソフト入れましょう、変なメールの添付ファイルは開けないようにしましょう。って感じで
基本的なことを行うことが大切なんだなって思ってる。

## 参考

- [バックオリフィス](https://atmarkit.itmedia.co.jp/ait/articles/0401/01/news041.html)
- [Back Orifice](https://japan.zdnet.com/glossary/exp/Back%20Orifice/?s=4)
【EC2/Amazon Linux2】 S3にアップロードした画像ファイルが削除できなくて調査したこと


# 始めに
RailsアプリケーションのAction Textを使用した画像アップロード機能のテストを行なった際、
画像の削除処理がS3に反映されない現象が発生しました。

本記事は、調査に使用したコマンドと調査観点をメモしています。

# インフラ構成
調査時点のインフラ構成図は下記となっています。
AppサーバーにIAMロールを付与しており、VPCエンドポイントを経由して、S3と通信を行う構成となっています。

![スクリーンショット 2022-05-20 18.31.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230985/8f6ebae8-2e97-1dff-a09d-ad238cc0b898.png)

# 調査内容


## 対象のEC2インスタンスからS3を操作することが可能か確認
下記コマンドを実行して、 `AccessDenied`が表示されていることを確認しました。

```shell
# 指定のバケットから一覧を取得できるか
aws s3 ls s3://指定バケット名

# 指定のファイルの確認することができるか
aws s3 ls s3://指定バケット名/ファイル名

# 指定のファイルを削除できるか
aws s3 rm s3://指定バケット名/ファイル名
# => delete failed: s3://指定バケット名/ファイル名 An error occurred (AccessDenied) when calling the DeleteObject operation: Access Denied
```

## RailsのコンソールからS3にアクセスが可能か確認する場合
Railsのコンソールから確認する場合は下記コマンドとなります。

```rb
# 初期化
client = Aws::S3::Client.new(region: 'ap-northeast-1' )
# => #<Aws::S3::Client>

# オブジェクトの取得
client.get_object(:bucket => '指定バケット名', :key => 'key番号').body.read

# オブジェクトの削除
client.delete_object(:bucket => 'bucket_name', :key => 'sample.txt')
```
## ポリシーの見直し

調査の結果から、権限周りの問題と考え下記設定値を見直しました。
- EC2に追加されているIAMロール
- バケットポリシー
- VPC エンドポイントポリシー

今回の原因は `VPC エンドポイントポリシー`に `deleteObject`の設定がなく削除ができなかったようです。
設定追加してあげて無事画像ファイルを削除することができました。

# 参考URL
https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Client.html
[小ネタ] Vueの静的ファイル配置

# この記事に関して

先に「[jestを使ってVue3のUnitテストをやってみようとして苦労した話](https://qiita.com/etnk/items/94156de78ffb9ffc532a)」という記事を書きました。その中で、wasmモジュールの扱いが残課題として残っている状態でした。それに関して調べているうちに、さらに前に書いた記事「[VueからWebAssembly（seed使用）を利用してみる。](https://qiita.com/etnk/items/3541e492862770c17341)」がちょっと無駄な事してた事に気づきました。nginxを使って頑張っていたのですが、そんな大掛かりな事しなくて良かったのです。

それに関しての補正記事です。この記事書いた後、この記事を上記記事に引用追記します。

# 参考にさせてもらった記事

https://qiita.com/skmtko/items/a83f836b48f24309916d

`src/asset`に置く場合と`src/static`に置く場合の扱いの違いを詳しく説明してくれています。
簡単に言うと、ビルドした時に画像ファイルを変換して埋め込む処理をする動作と、ファイルをそのまま成果物フォルダ（distなど）にコピーする動作という違いです。

そうです、wasmモジュールファイルも、成果物フォルダにコピーする元フォルダにおけばよかったのです。

# publicフォルダに配置

前述記事の時とはフォルダ構成が変わった様です。自分のプロジェクトでは`src/static`フォルダは存在しませんでした。しかし、成果物フォルダにそのままファイルコピーされている`favicon.ico`がどこにあるか探すと、`public`フォルダにありました。
そこで、wasmファイルとpublicフォルダに置いた所、ビルド成果物では該当フォルダにコピーされました。そして開発モードでも普通に読み込めました。

# 課題

残念ながら、本題である所のUnitテストでwasmモジュール読み込む所の問題はまだ解消出来てないです。引き続き調査します。

※後に解消しました。拙記事「[jestでAPIなど他リソースが必要な機能のテストをしてみる](https://qiita.com/etnk/items/b97055ac5faca35611b2)」
Arduino Due の高速化

Arduino Due はクロック周波数が 84 MHz と Arduino Uno (16 MHz) と比べて高速ですが、色々と高速化する必要があったので、使った方法をいくつかまとめました。気が向いたら追記・修正予定です。
作業環境は macOS Big Sur/Monterey、Arduino IDE を使用しています。

## ```digitalRead()``` の高速化
Arduino Uno とは少し記法が違います。

```c
REG_PIOD_SODR = 0b1111 // これで 25~28 番 pin が HIGH
REG_PIOD_CODR = 0b1111 // これで 25~28 番 pin が LOW
```

この方法でやると 20 ns 程度 (2 clock?) で HIGH/LOW の切り替えが可能です。
A~D に割り振られているので、使用する pin に合わせて変更します。

## コンパイルオプションの変更
Arduino IDE でコンパイルオプションを変更するには、まず環境設定の
```
より詳細な情報を表示する
```
のコンパイルにチェックを入れます。この状態でコンパイルを実行すると３行目ぐらいに
```
/Users/USERNAME/Library/Arduino15/packages/arduino/hardware/sam/1.6.12
```
という感じのパスが表示されます。このフォルダ内の "platform.txt" にコンパイル時の設定が保存されています。
今回は最適化オプションを -Os から -O3 に変更してやります。こうすることで、```for``` や ```while``` でループする際の処理が少し速くなって 45 ns (4 clock?) ぐらいのデッドタイムで繰り返し処理が可能です。ただ、確認はしていませんが繰り返し回数が決まったループであれば、その回数だけ書いてしまう方が速い（はず）です。
今回は繰り返し処理の間に適当な間隔が欲しかったので、あえて ```for``` を使っています。

## 割り込み関数 ```attachInterrupt()```
外部入力を受けてからすぐに処理を開始したい場合、最初は
```c
void loop() {
  int trigger = 0;
  while (trigger != 1) {
    trigger = REG_PIOD_PDSR & 0b1; // digitalRead(25) の高速版
  }
  // 25 番 pin が HIGH になった以降の処理
}
```
と書いていたのですが、この方法だと処理後に先頭に戻る際にも時間がかかってしまうので、25 番 pin の状態を 45 ns ごとに確認することになります。そのデッドタイムを減らすためには、割り込み関数が使えます。割り込み関数を使用する場合は
```c
void setup() {
  attachInterrupt(25, USERFUNCTION, RISING);
  // 使用する割り込み関数の準備：25 番 pin が LOW -> HIGH で USERFUNCTION を実行
}

void loop() { // loop の中は空で良い
}

void USERFUNCTION() { // 割り込み関数の中身
}

void serialEvent() { // シリアルを受け取った時の割り込み処理も書ける。
}
```
と書くことで、25 番 pin が LOW から HIGH に変わった瞬間に ```USERFUNCTION()``` 内の処理が開始されます。```RISING``` 以外にも ```LOW, CHANGE, FALLING, HIGH (Arduino Due、Zero、MKR1000 のみ)``` が指定できます。
詳細は Arduino リファレンスを参照してください。

https://garretlab.web.fc2.com/arduino_reference/language/functions/external_interrupts/attachInterrupt.html

逆に割り込まれたくない場合は ```noInterrupts()``` と ```interrupts()``` で挟んでやることで、命令の実行中に割り込まれることがなくなります。意図していない割り込みを防ぐためにタイミングがシビアな部分にはこれが必要です。

気が向いたら Arduino Uno との比較等もまとめたいと思います。
scipy.stats: 正規分布の検定（オムニバス検定） normaltest

# 正規分布の検定（オムニバス検定） `normaltest`

データは正規分布からの標本といえるか？の検定。

$H_0$:母分布は正規分布である。

$H_1$:母分布は正規分布ではない。

以下の 2 論文に基づいたオムニバス検定である。

1. D'Agostino, R. B. (1971), "An omnibus test of normality for
           moderate and large sample size", Biometrika, 58, 341-348
2. D'Agostino, R. and Pearson, E. S. (1973), "Tests for departure from
           normality", Biometrika, 60, 613-622

`normaltest(a, axis=0, nan_policy='propagate')`

## 1.　正規乱数について検定を行う

平均値=50，標準偏差=10 の正規乱数 25 個について検定を行う。


```python
from scipy.stats import norm
import numpy as np
np.random.seed(123)

x = np.round(norm.rvs(loc=50, scale=10, size=25), 1)
print(*x)
```

    39.1 60.0 52.8 34.9 44.2 66.5 25.7 45.7 62.7 41.3 43.2 49.1 64.9 43.6 45.6 45.7 72.1 71.9 60.0 53.9 57.4 64.9 40.6 61.8 37.5



```python
normaltest(x)
```




    NormaltestResult(statistic=1.0656167729164954, pvalue=0.5869542584547112)



オムニバス検定とは，一般に，同じデータに対する独立な $k$ 個の正規分布にしたがう検定統計量の二乗和が自由度 $k$ の $\chi^2$分布に漸近するというものである。

今回は，`skewtest(x)` および `kurtosistest(x)` が返す**独立な** `z 値` の二乗和が自由度 2 の $\chi^2$ 分布に近似できるとする仮説検定である。


```python
from scipy.stats import skewtest, kurtosistest
from scipy.stats import chi2
s, ps = skewtest(x) # s は歪度の検定の Z 値
k, pk = kurtosistest(x) # k は尖度の検定の Z 値
print(s, k)
statistic = s**2 + k**2 # 検定統計量
print('statistic =', statistic, '　　df = 2')
print('p value =', chi2.sf(statistic, 2))
```

    -0.022210278084285384 -1.032048194835839
    statistic = 1.0656167729164954 　　df = 2
    p value = 0.5869542584547112


$p \gt 0.05$ ゆえ，帰無仮説は棄却できない（$p = 0.587$）。したがって，このデータは正規分布に従っていないとはいえないと結論する。

## 2.　正規乱数ではないものについて検定を行う

自由度 1 の $t$ 分布（すなわちコーシー分布）にしたがう乱数 25 個に対して検定を行ってみる。


```python
from scipy.stats import t
import numpy as np
np.random.seed(123)

y = np.round(t.rvs(df=1, loc=50, scale=10, size=25), 1)
print(*y)
```

    16.2 58.9 -0.0 42.4 44.1 45.3 56.6 79.1 119.6 26.6 20.6 46.9 30.4 51.7 54.6 49.3 70.2 88.0 50.3 61.7 21.9 108.7 671.3 87.3 64.7



```python
normaltest(y)
```




    NormaltestResult(statistic=58.02809862697257, pvalue=2.5081787582156243e-13)



$p \lt 0.05$ ゆえ，帰無仮説を棄却する（$p \lt 0.00001$）。したがって，このデータは正規分布に従っていないと結論する。


```python

```
C#のInterfaceを使ってみた

2022.5.26 12日目　　長らく投稿できずにいました。仕事が忙しく、毎日がほぼ勉強でしたので、これからまとめていこうかと思います。

## 今回まとめる事
　Interface　という機能について

## 参考資料
https://e-words.jp/w/%E3%82%A4%E3%83%B3%E3%82%BF%E3%83%BC%E3%83%95%E3%82%A7%E3%83%BC%E3%82%B9.html

https://www.sejuku.net/blog/87543

## Interfaceって何？？
そもそもInterfaceとは何なのでしょうか？
言葉の意味としては、接点、境界面、接触面、橋渡しなどがあるそうです。IT関連では、2つのものが接続・接触する箇所や、両者の間で情報や信号などをやり取りするための手順や規約を定めたものだそうです。

## Interfaceで何ができるの？
私がInterfaceを知ったのは、会社の先輩に、Interfaceを作ってバグが出た時わかりやすいようにしておいてね(^^)と言われたことがきっかけでした。
UIの処理を考えていましたが、Updateの処理の中にたくさんのコードが連なり、このままいくとUpdateだけで500行を超えるのでは！？となっていた私にとっては、とてもありがたい教えでした。

### できる事
「このInterfaceを使うときは、このメゾッドの中身を必ず作ってね」
といった、コードを書く時の決まり事を作ることができます。

```C#:Interfaceを定義したクラス
namespace TestInterface
{
    interface ITestInterface
    {
        void UpdateInterface(int x);
    }
}

```

```C#:Interfaceを使用するクラス
namespace TestInterface
{
    public class InterfaceTest: MonoBehaviour, ITestInterface
    {
        public void UpdateInterface(int x)
        {

        }
    }
}
```

クラスは分けて定義するのがいいそうです。
また、
```C#:Interfaceを使用するクラスの中
public void UpdateInterface(int x)
{

}
```
↑の関数が定義されていないと、下の画像のようなエラーが出ます。
![bandicam 2022-05-26 23-09-03-660.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1940156/0d1aba1b-ca5c-cac4-b3e6-08f49bfe1418.jpeg)
（実装しませんってなんやねん！してくださいにしてください）

このような感じで使用できます。
今回の仕事で使ったものは、コールバック関数を置いて、初期化する関数にUpdateに書いていた処理を移動させました。
そうすることで、あ、この処理が渡されたらこのコードが呼ばれて、こういう処理をするのか、とわかりやすくなりました。
（その代わり初期化関数が、めためた長くなりますが、わかりやすいのでよし）

短いですが以上です。
GitLabのマージリクエストのchanges

# 内容
開発中のマージリクエストでのコード差分が意図した差分にならないことが
あったのでGitLabのchangesに出る内容について改めて確認しました。

# 現象
発生した現象はこのようなイメージです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234640/f908bc72-fd35-660e-dce3-d3eb19ba221a.png)

イメージとしてはmasterからf1、f2ブランチを切り、
リリース時にcheck、masterとmerge（masterのみsquashでmerge）をしている状態。
このときf1ブランチは特に問題なくmasterにmergeできましたが、
f2でf1の開発内容が入った最新のmasterをpullし、checkに対して
マージリクエストを作成した際に、既にcheckにpushされたはずのf1ブランチの開発内容が、出てきてしまうというものです。

# git diff
そもそもgitにはgit diffコマンドがあります。 
このコマンド、実はgit diff f1 f2 といった２つのブランチを比較する際に、
２通りの書き方があります。
①ダブルドット　　git diff f1..f2　※デフォルト
②トリプルドット　git diff f1...f2 

これらの違いは
**■ダブルドット**
→ベースブランチの最新状態とトピックブランチの最新バージョンの差を表示する
**■トリプルドット**
→両ブランチの最新共通コミットとトピックブランチの最新バージョンとの差を表示する

画像にするとこんな感じです。
![uWWDV.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234640/1c6986da-1af9-b28c-adf1-b718489dda5b.png)


GitHubDocsにも詳細が書いてありますので、興味ある方はご覧ください。
https://docs.github.com/ja/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-comparing-branches-in-pull-requests#three-dot-and-two-dot-git-diff-comparisons


# マージリクエストにおけるdiff
ここからが本題です。
GitLabのマージリクエストでchangesは何の差分が表示されるかというと、
「トリプルドット」での差分になります。
参考
https://docs.gitlab.com/14.10/ee/development/diffs.html#merge-request-diffs-against-the-head-of-the-target-branch

# なんで問題が発生したか
ここまでくればなぜ差分がおかしかったか理解できました。


# どうすればいいのか
以下の方法しかなさそう
①masterへのmergeの際にsquashしない
②master→checkへ再マージする
とりあえず②で運用ですかね。。

以上です。
Exam Readiness DOP : 分野 6:高可用性、対障害性、災害復旧

# はじめに
AWS DOPの試験対策で[Exam Readiness: AWS Certified DevOps Engineer – Professional (Japanese)](https://explore.skillbuilder.aws/learn/course/117/play/503/exam-readiness-aws-certified-devops-engineer-professional-japanese)を視聴したので、内容をまとめます。

# アジェンダ
| 分野 | 内容 |
|------|---------|
|    1  |   [ SDLC の自動化](https://qiita.com/tetsuya_tech/items/3da9ac5042f40d1577ba)|
|    2  |   [設定管理とIaC](https://qiita.com/tetsuya_tech/items/1691599cebc9ebafa730)|
|    3  |  [モニタリングとロギング](https://qiita.com/tetsuya_tech/items/338385fe2cdf2265a543)|
|    4  |  [ポリシーと標準の自動化](https://qiita.com/tetsuya_tech/items/baa999857d805fae3842)|
|    5  |   [インシデントとイベントレスポンス](https://qiita.com/tetsuya_tech/items/24315754f4af20743423)|
|    6  | 高可用性、対障害性、災害復旧|


# 高可用性

- マルチリージョンアーキテクチャの全体像
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/951272/17e25f91-e06e-80ba-e32f-d17a263d7f7d.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/951272/2627ceed-7a0b-8f0f-98b2-b26a62b0bda5.png)

# スケーラビリティ
## Lamdba@Edge
- エンドユーザに近いエッジロケーションの可用性を確保
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/951272/91448678-288e-3f2d-158c-8770a9ff8ef6.png)


## 中間層のスケーリング
- SQSキューは一方高のキューのため、双方向にするには複数使用する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/951272/a4ef2589-3555-5e45-93a5-9a0a1fc8df79.png)


- 複数のワーカーが処理するためにはSNSを経由する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/951272/7e90d717-84e2-e760-fcc0-0ba264b0e5ba.png)

## データストレージのスケーリング
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/951272/d42bdc52-18b7-c047-44ee-1fbf9c2e715d.png)

- DBの場合はよく利用するデータをElastiCacheでキャッシュする方法もある。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/951272/6ba5cbe9-701b-ddcb-eefe-950f93147a0f.png)

# 災害対策
- RPO（目標復旧時点）：いつのデータを復元するか。バックアップの頻度に関わる。
- RTP(目標復旧時間)：ダウンタイムはどれくらいか。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/951272/9e433414-b5f9-51aa-a084-02449e5fe893.png)

- バックアップと復元：スナップショットのみ取得
- パイロットライト：低スペックでデータの同期のみ行う
- ウォームスタンバイ：低スペックでアプリケーションを起動
- ホットスタンバイ：同等スペックのDR環境を用意

# 問題例
- ELB、EC2、RDS。自己回復ソリューションを実装。
-> EC2のAuto Scalingグループと共に、EC2　CPU使用率に合わせてスケーリング。　RDSのソリューションは費用に応じて検討。
- Webサーバでリクエストが増加しページのロードが遅延
-> CloudFormation、Elastic Beanstalk、Auto Scalingを使用してアプリケーションを再デプロイ。1秒あたりのリクエストに応じてスケーリング。
- S3バケットからEC2で処理し別のS3バケットへ。スケーリングが過度だが終了しない。
-> アプリケーションログを分析し、原因を探す。
【Laravel】whereHasとwithの違い

## 環境
Laravel v9.5.1 (PHP v8.1.3)


## with
```eager load```でN+1問題が解消される。
```php
$users = User::with('post')->get();

foreach ($users as $user) {
    echo $user->posts;
}
```

```
select * from users
select * from posts where id in (1, 2, 3, 4, 5, …)
```

https://readouble.com/laravel/9.x/ja/eloquent-relationships.html

## whereHas
リレーション先の条件でフィルタリングした結果を取得。

```php
use Illuminate\Database\Eloquent\Builder;

$users = User::whereHas('posts', function (Builder $query) {
    $query->where('users.organization_id', $user->organization_id);
})->get();
```

```
select * from `posts` where exists (select * from `users` where `posts`.`user_id` = `users`.`id` and `users`.`organization_id` = ?)
```

https://readouble.com/laravel/9.x/ja/eloquent-relationships.html?header=Morph%2520To%25E3%2583%25AA%25E3%2583%25AC%25E3%2583%25BC%25E3%2582%25B7%25E3%2583%25A7%25E3%2583%25B3%25E3%2581%25AE%25E3%2582%25AF%25E3%2582%25A8%25E3%2583%25AAv

## 参考

https://stackoverflow.com/questions/30231862/laravel-eloquent-has-with-wherehas-what-do-they-mean
Visual Studio で「デバッグアダプターを起動できませんでした」と出てデバッグ実行できなくなった（ブラウザの問題ではない場合）

# 事象
Microsoft Visual Studio Professional 2019 にて、デバッグ実行をしようとすると

>１つ以上のエラーが発生しました。　
>
>デバッグアダプターを起動できませんでした。追加情報を出力ウィンドウで確認できる場合があります。
>
>操作は取り消されました。

というエラーメッセージが表示された。出力メッセージを見ても
```
 プログラム  はコード -1 (0xffffffff) で終了しました。
```
で終わってる…

# 結論

https://stackoverflow.com/questions/71342354/failed-to-launch-debug-adapter-in-visual-studio-2022

こちらのstack overflow の内容で解決。

>Deleting the whole directory (C:\Users\username\vsdbg\vs2017u5) and then pressing F5 forces Visual Studio to re-create the directory and debugging now works.
>
>訳：C:\Users\username\vsdbg\vs2017u5 をディレクトリごと消して再起動するとデバッグできるようになる

# 所感とか試したこととか

記事作成時点では、検索すれどもほぼ全部「ブラウザがうまいこと起動しないんだよね？」という記事が多く上記のページにたどりつくのに苦労したため備忘の意味も込めて記事に。こちらはブラウザを必要としないプロジェクトでもこのエラーが出たり、それらでは解決せず非常に困った。**こういう時はメッセージをそれっぽい英語にして検索するのが一番**ですね…

### 試したけど関係なかったこと一覧
* ソースコードの修正(前まで動いていたものと全く同じものに)
* Visual Studio の再起動
* Visual Studio の設定値を変更してみる(上記にあるブラウザ系のエラーに関するもの。解決せず)
* PCの再起動(Port系を疑って。もちろん解決せず)
* Process の検索(デバッグ実行するためのPortが塞がれてる？と思い。まぁ再起動で空かないんならそりゃ無い、とは思いつつ…)
【Django】makemigrationsとmigrateについて

Djangoにて使用するmakemigrationsとmigrateコマンドについて記載します
## makemigrationsとは
makemigrationsは、models.pyに記載したカラム名は、文字列型などの情報をmigrationファイルに記載します
まずmodels.pyに以下のように記載したとします
```models.py
from django.db import models
class Product(models.Model):
  title = models.CharField(max_length=120)
  description = models.TextField(blank=True, null=True)
  price = models.DecimalField(decimal_places=2, max_digits=1000)
  summary = models.TextField(blank=True, null=False)
  featured = models.BooleanField(null=True)
```
その後にmakemigrationsを実行します
```
$ python manage.py makemigrations
Migrations for 'products':
  products/migrations/0001_initial.py
    - Create model Product
```
そうするとmigrationsディレクトリに以下に0001_initial.pyファイルが作成されます
![スクリーンショット 2022-05-24 21.45.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2281678/6926b23f-61fc-477c-698c-980b98546dae.png)
中身は以下のようになってます
```0001_initial.py
# Generated by Django 4.0.4 on 2022-05-24 12:12

from django.db import migrations, models


class Migration(migrations.Migration):

    initial = True

    dependencies = [
    ]

    operations = [
        migrations.CreateModel(
            name='Product',
            fields=[
                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('title', models.TextField()),
                ('description', models.TextField()),
                ('price', models.TextField()),
            ],
        ),
    ]
```
makemigrationsを行うことでDBへ登録するためにmigrationファイルを作成することができます。
DBへ登録する前に最終チェックして問題あればファイルを削除して、models.pyを修正、makemigrationsを実行すれば良いでしょう。

## migrateとは
migrateは、DBにmigrationファイルに記載した内容を登録します。
実行方法は、以下です
```
$ python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, products, sessions
Running migrations:
  Applying products.0001_initial... OK
```
ここでいうadmin, auth, contenttypes, sessionsのついては、デフォルトのsettings.pyのINSTALLED_APPSに記載していて、DBを使用するアプリケーションです。

migrateするには、makemigrationsで作成したmigrationファイルが必要です。
よって、migrationsディレクトリに存在するファイルは、基本的には消さないほうが良いでしょう。
消すタイミングとしては、DBを最初の状態に戻る場合、
DBを削除し、migrationsディレクトリ内を削除することで、
特にエラーなく、最初の状態の戻すことができます。

## まとめ
Djangoを学習している駆け出しエンジニアの方でDB周りに躓く場合、
まずは

* models.pyを修正
* python manage.py makemigrations
* python manage.py migrate
上記順番で実施すればいいんだなぁってことを頭に入れておくのが良いと思います。
Exam Readiness DOP : 分野 5:インシデントとイベントレスポンス

# はじめに
AWS DOPの試験対策で[Exam Readiness: AWS Certified DevOps Engineer – Professional (Japanese)](https://explore.skillbuilder.aws/learn/course/117/play/503/exam-readiness-aws-certified-devops-engineer-professional-japanese)を視聴したので、内容をまとめます。

# アジェンダ
| 分野 | 内容 |
|------|---------|
|    1  |   [ SDLC の自動化](https://qiita.com/tetsuya_tech/items/3da9ac5042f40d1577ba)|
|    2  |   [設定管理とIaC](https://qiita.com/tetsuya_tech/items/1691599cebc9ebafa730)|
|    3  |  [モニタリングとロギング](https://qiita.com/tetsuya_tech/items/338385fe2cdf2265a543)|
|    4  |  [ポリシーと標準の自動化](https://qiita.com/tetsuya_tech/items/baa999857d805fae3842)|
|    5  |   インシデントとイベントレスポンス|
|    6  | [高可用性、対障害性、災害復旧](https://qiita.com/tetsuya_tech/items/317bb98700b7b59026c7)|


# トラブルシューティング
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/951272/404e070c-74c3-1f5a-3887-f6f948c88336.png)

各サービスの連携が肝要。

## ロギングとモニタリングの連携
 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/951272/31fcd95c-84b7-9292-d078-8f7855123210.png)

## APIコールの通知
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/951272/0f3bef85-0973-f9b8-f78d-3ce0e6ff33b8.png)

- 設定管理

# 自動復旧
可能な限りオートメーションを利用して復旧する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/951272/ddc396c3-872b-b445-89bc-07494744fa1b.png)
- 全てのログデータが記録される。それを利用してトラブルシューティングを行う。

# Auto Scalingとライフサイクルフック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/951272/6726dd19-b7fe-72ab-4c9a-d9ae886bf6ab.png)

## Auto Scalingサービスの停止
- Launch:EC2を追加
- Terminate:EC2を削除
- AlarmNotifications:CloudWatchアラームから通知を受け取る
- ReplaceUnhealthy:異常とマークされたインスタンスを削除し代替インスタンスを生成
- HealthCheck:インスタンスのヘルスチェック
- AZRebalance:AZ内でEC2の数のバランスを取る
- AddToLoadBalancer:インスタンス起動時にアタッチされたロードバランサーに追加

## Auto Scaling終了ポリシー
- デフォルト:AZで均等な可用性を確保
- OldestInstance:最も古いものを終了
- NewestInstance:最も新しいものを終了
- AllocationStrategy:優先度の低いタイプのオンデマンドインスタンスを高いものに置き換える
- OldestLaunchConfig:グループを更新し、最も古い起動設定のインスタンスを削除
- OldestLaunchTemplate:グループを更新し、最も古い起動テンプレートを使用するインスタンスを削除
- ClosestToNextInstanceHour:次の課金時間に最も近いインスタンスを削除

## ライフサイクルフック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/951272/d45ee86c-87cb-fad4-ce05-16a9ebe9c99f.png)

## CodeDeployのライフサイクルイベント
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/951272/97d1cfcb-bf00-eeda-9217-412af9b9e8a7.png)
- 各EC2インスタンスにCodeDeployエージェントをインストールする

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/951272/a2f0d212-9bab-616b-51ce-28786b5c782c.png)

# 問題例
- タグポリシーに準拠していないEC2インスタンスを終了
-> AWS Config内のルールを設定。違反しているインスタンスはCloudWatchイベントを使用してLambda関数を実行し終了する。
- SQSキューの深さに基づいてEC2をスケーリング。CPUを大量に消費する実行時間の長いジョブが含まれ、処理中にスケールインする。
-> メッセージの処理中にインスタンスをAuto Scalingのstandby状態にして、処理が終わったらinServiceに戻す 
- コードリポジトリでS3をデータストア。整合性の維持、EC2へセキュリティ高くデプロイ。
-> オブジェクトを削除する際に多要素認証、バージョニングを有効。認証情報をハードコーディングせず、S3バケットへのアクセス権限をもつIAMロールをEC2にアタッチ。
- CodeDeployでAuto Scaling内にEC2インスタンスをデプロイ。ELBのヘルスチェックが失敗。
-> ReplaceUnhealthyプロセスを停止し、壊れたマシンにサインインしトラブルシューティング。
- CodeDeployにValidateCodeイベントを追加し、コードがサービスに配置される前に正常に機能していることを確認。
【Laravel】バリデーションメモ

# Laravelのバリデーションで悩んだ話

## やりたいこと
　4桁の数字を入力するフォームで、バリデーションをかきたい！

## 正規表現
- minが最小値でmaxが最大値ね～ふむふむ！
- …あれ？
- ぴったり○桁って、自分で書かなきゃ？
- こ、こんな感じか？

```php
$validateRules = ['number'=>'regex:[0-9]{4}'];
```

- 実行結果から、うまくいってなさそう（正規表現うろ覚えすぎる）
- 行頭・行末を指定してあげたら、なんとかいけた…これが正しい書き方なのか不安はあるけれど…！
```php
$validateRules = ['number'=>'regex:/^[0-9]{4}$/'];
```

## エラーメッセージ
- おや？
- 組み込みバリデーションルールじゃないので、エラーメッセージがいい感じにでないな？
- ということで公式の書き方を確認
  - [Laravel 8.x バリデーション
](https://readouble.com/laravel/8.x/ja/validation.html )
```php:公式のお手本
$validator = Validator::make($input, $rules, $messages = [
    'required' => 'The :attribute field is required.',
]);
```
- なるほどね…つまりこんな感じかな？
```php:
$validator = Validator::make($input, $rules, $messages = [
    'regex:/^[0-9]{4}$/' => 'numberは4桁で入力してください。',
]);
```
- うーん、失敗！！
- キーは「regex」だけでよかった！！
```php:
$validator = Validator::make($input, $rules, $messages = [
    'regex' => 'numberは4桁で入力してください。',
]);
```

## 感想

ITの技術職に転職して約１カ月…アウトプットのために今日から記事を書き始めました！
レベルが低くて毎日泣いちゃいそうですが、ちょっとずつ頑張りたいです！
GitHub Actionsを利用してplaywrightを使ったAzure Functionsアプリをデプロイする(Python)

# はじめに
playwrightは実行前に以下のコマンドを実行してブラウザをインストールしておく必要がある。
```bash
playwright install
```
このときデフォルトではユーザーディレクトリ下にインストールされるが、環境変数の`PLAYWRIGHT_BROWSERS_PATH`にインストール先のパスを設定しておくことで任意の場所にブラウザをインストールすることが可能になる。
これを利用してAzure Functionsでplaywrightを使えるようにする。

# 今回動かすアプリ
コードは[公式のサンプルコード](https://playwright.dev/python/docs/intro#usage)をAzure Functions用に少し変更した。
アプリの内容は`http://playwright.dev`にアクセスし、ページのタイトルを返すというもの。

ポイントは`executable_path='./browser/chromium-1005/chrome-linux/chrome`の部分。
`executable_path`はブラウザの実行ファイルを指定するための引数で何も指定しないとデフォルトでインストールされているブラウザを使用する。
今回はブラウザのインストール時に`PLAYWRIGHT_BROWSERS_PATH`を`./browser/`としているため`executable_path`は`./browser/chromium-1005/chrome-linux/chrome`とする。

```python:__init__.py
import azure.functions as func
from playwright.sync_api import sync_playwright


def main(req: func.HttpRequest) -> func.HttpResponse:
    with sync_playwright() as p:
        browser = p.chromium.launch(executable_path='./browser/chromium-1005/chrome-linux/chrome')
        page = browser.new_page()
        page.goto("http://playwright.dev")
        res = page.title()
        browser.close()

    return func.HttpResponse(res)
```
```:requirements.txt
azure-functions
playwright
```
# GitHub Workflowを書く
環境変数の`PLAYWRIGHT_BROWSERS_PATH`を設定して作業ディレクトリ内にブラウザがインストールされるようにする。
あとは、ブラウザと一緒にAzure Functionへデプロイ。

```yaml
name: Build and deploy Python project to Azure Function App

on:
  push:
    branches:
      - master
  workflow_dispatch:

env:
  AZURE_FUNCTIONAPP_PACKAGE_PATH: '.'
  PYTHON_VERSION: '3.9'

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v2

      - name: Setup Python version
        uses: actions/setup-python@v1
        with:
          python-version: ${{ env.PYTHON_VERSION }}

      - name: Create and start virtual environment
        run: |
          python -m venv venv
          source venv/bin/activate

      - name: Install dependencies
        run: pip install -r requirements.txt

      # ブラウザのインストール
      - name: Install browser
        run: playwright install chromium
        # 環境変数の設定（作業ディレクトリのbrowserディレクトリにインストール）
        env:
          PLAYWRIGHT_BROWSERS_PATH: ./browser

      - name: 'Deploy to Azure Functions'
        uses: Azure/functions-action@v1
        id: deploy-to-function
        with:
          app-name: 'playwright-azurefunc' # 適宜変更
          slot-name: 'production'
          package: ${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }}
          publish-profile: ${{ secrets.AzureAppService_PublishProfile }}
          scm-do-build-during-deployment: true
          enable-oryx-build: true
```
【PHP】nullableな型

## 環境

## nullableな型

型宣言の前に```?```をつけると、指定した型か```null```が許容される。


```php
public static function createPostBy(
    int $userId,
    string $type,
    string $content,
    ?DateTime $deletedAt
)
{
   self::create([
      ...
   ]);
}
```

```?```をつけずに引数に```null```を入れていると下記のようにエラーが出る。
```
 Argument #2 ($deletedAt) must be of type int, null given, called in 
```

## 参考

https://www.php.net/manual/ja/migration71.new-features.php
VSCodeのターミナルで「pyenv global」で「pyenv version」が書き換わらない

# 状況
`pyenv global x.x.x`で`pyenv version`が書き換わるはずなのに、VSCode内のターミナルで書き換わらない（普通のターミナルでは正しく書き換わる）

```bash
$ pyenv global 3.8.10
$ pyenv versions # pyenv globalの設定が効いてない！                                                                                          
  system
* 3.10.0 (set by PYENV_VERSION environment variable)
  3.7.9
  3.8.10
  3.9.11
```
のようになる

## 環境

VSCode　1.67.2
Python(VSCodeの拡張機能)　v2022.6.2

# 解決方法
VSCodeのSettingで「pyenv」と検索→「Python > Terminal: Active Environment」のチェックを外す
![スクリーンショット 2022-05-26 16.26.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638747/6361562c-41ea-8375-b506-cb6a29eaa4bb.png)
基本情報（２進数の足し算と引き算）

**コンピュータには「引き算」という概念ありません**というパワーワードを見ました。
だけど引き算はできる。さて、どうやるのか。

一旦、足し算からおさらいします。

```
 1111
+ 101
------
10100
// 1 + 1 = 0（繰上げ1)
```
5-3を計算させたい場合は5+(-3)の計算ができれば、足し算と使って引き算と同じ結果を
得ることができるようです。

## 負の数の表し方

引き算を知らなくても、負の数を表現できれば足し算で答えを求められます。

条件
* 数値を8ビットで表すことにする（８ビットは２進数で８桁）
* 先頭の1ビットが０なら正の数、１なら負の数とする

例えば10進数の「3」を
```
正の数 0 0 0 0 0 0 1 1 ( 3)
負の数 1 0 0 0 0 0 1 1 (-3)
```

00000011 + 10000011 = 100000110
3と-3を足したら0にならないといけないのに上記はそうなっていません。

そこで**補数**という概念が出るそうです。

補数は言葉の通り「補う数」という意味。

例えば10進数で123という数字があったとします。

```
999 - 123  = 876　 // 9の補数と呼ぶ
1000 - 123 = 877 // 10の補数と呼ぶ
```

999は3桁の最大値で、1000は次の桁に繰り上がる数です。

２進数では「1の補数」と「２の補数」の2つの補数があります。

例えば2進数で0011という数字があったとすると

```
1111 - 0011  = 1100  // 1の補数
10000 - 0011 = 1101　 // 2の補数
```

4桁の最大値は1111で次の桁に上がる数は10000です。

２の補数を使って計算をしてみます。

```
  00000011
+ 11111101
-----------
 100000000
```
8ビットから溢れた９ビット目を無視すると00000000になる。
つまり0になります。

ある数値に対する2の補数表現は、負の値として使えます。
このことから、コンピュータは負の数を表すのに２の歩数を使うようです。

２の補数は次のように求めることができます
```
00000011 ( 3)
11111100 // 全てのビットを反転させる(0と1を入れ替える)
11111101 (-3) // それに１を加算する
```

## 引き算の流れ
5-3を2進数に変換して計算します。
```
0101 - 0011
     + (-0011)
     + 1101
```
0101 + 1101 = 0010(桁溢れした先頭のビットは切り捨て)

## まとめ
この章はちょっと、しっくりこなかったので復習しようと思います。
R で幾何平均を求めるには...

標準の関数がないとお嘆きの方々が，たどり着いたページに

$\displaystyle \sqrt[n]{\prod_{i=1}^{n} x_i}$

に基づいて

```R
prod(x)^(1/length(x))
```

あるいは，ひどいものだと

```R
max(cumprod(x))^(1/length(x))
```

なんて書いてあったら，そのまま信じちゃいけない。

以下の実験は，平均値=100，標準偏差=5 の正規乱数を発生させて，幾何平均を求めるもの。

まずは，サンプルサイズ 100 の場合。

いずれも正しい答えを出している。

```R
> set.seed(123)
> n = 10
> x = rnorm(n, 100, 5)
> prod(x)^(1/length(x))
[1] 100.2728276899091
> max(cumprod(x))^(1/length(x))
[1] 100.2728276899091
> exp(mean(log(x)))
[1] 100.272827689909
```

サンプルサイズ 160 くらいになると，前二者は突然発狂する。

```R
> set.seed(123)
> n = 160
> x = rnorm(n, 100, 5)
> prod(x)^(1/length(x))
[1] Inf
> max(cumprod(x))^(1/length(x))
[1] Inf
> exp(mean(log(x)))
[1] 99.81754279797046
```

教訓：教科書の定義式をそのままプログラムしてはいけない。
usdzファイルからサムネイルを出力する

### 実はusdzファイルからサムネイル画像を作れる

ステップ1
QuickLookThumbnailingをimportする

```swift
import QuickLookThumbnailing
```
ドキュメント

https://developer.apple.com/documentation/quicklookthumbnailing

ステップ2
usdzファイルのpathを生成

```swift
 func generateThumbnail(for resource: String,
                           withExtension: String = "usdz",
                           size: CGSize) {
        guard let url = Bundle.main.url(forResource: resource, withExtension: withExtension) else { return }
}
```

ステップ3 QLThumbnailGeneratorをインスタンス化(シングルトン）

```swift
let generator = QLThumbnailGenerator.shared
```

ステップ4 サムネイルにするためのrequestを作る
```swift
// 引数にパスとサイズ、大きさ、representationTypesを入れる。
// representationTypes-> 表示するサムネイルの画像の種類。他にiconとか色々ある。
let request = QLThumbnailGenerator.Request(fileAt: url,
                                                   size: size,
                                                   scale: scale,
                                                   representationTypes: .all)
```

ステップ5 実際にrequestを飛ばす。

```swift
 generator.generateRepresentations(for: request) { (thumbnail, type, error) in
            DispatchQueue.main.async {
                if thumbnail == nil || error != nil {
                    print(error?.localizedDescription ?? "")
                } else {
                    self.thumbnailImage = Image(uiImage: thumbnail!.uiImage)
                }
                
            }
        }
```

全体のコード

```swift
// Generatorクラス作成し、ObservableObjectに準きょさせてViewModelっぽく使ってる
class ThumbnailGenerator: ObservableObject {
    @Published var thumbnailImage: Image?
    func generateThumbnail(for resource: String,
                           withExtension: String = "usdz",
                           size: CGSize) {
        guard let url = Bundle.main.url(forResource: resource, withExtension: withExtension) else { return }
        let scale = UIScreen.main.scale
        let request = QLThumbnailGenerator.Request(fileAt: url,
                                                   size: size,
                                                   scale: scale,
                                                   representationTypes: .all)
        let generator = QLThumbnailGenerator.shared
        generator.generateRepresentations(for: request) { (thumbnail, type, error) in
            DispatchQueue.main.async {
                if thumbnail == nil || error != nil {
                    print(error?.localizedDescription ?? "")
                } else {
                    self.thumbnailImage = Image(uiImage: thumbnail!.uiImage)
                }
                
            }
        }
    }
}
```
Gentooインストール時に強いパスワードを設定しろと要求された

# パスワードで悩んでるキミ！もうすぐゴールやんけ！

最近インストールしていて強めのパスワードを設定するように要求される。
原因は分かっているのだが、めんどくさいので書きかえて回避する。
```:vimアレルギー注意報
chroot # vim /etc/security/passwdqc.conf
```
開けましたら`min=`を探してください
```:passwdqc.conf
min=1,1,1,1,1
```
と書きかえて保存

これでとりあえずは簡単なパスワードも通ります。

時間があれば原因の解説と解決を投稿しようと思います。

#gentooinstallbattle
【PHP】4種類のnull判定

## 環境
Laravel v9.5.1 (PHP v8.1.3)

## null判定


### is_null
```php
if (is_null($hoge)) {
   echo 'nullだよ';
}

=> "nullだよ"
```

### empty
```php
if (empty($hoge)) {
   echo 'nullだよ';
}

=> "nullだよ"
```

### ==
```php
if ($hoge == null ) {
   echo 'nullだよ';
}

=> "nullだよ"
```

### ===
値と型が完全に一致しているか判定できる。
```php
if ($hoge === null ) {
   echo 'nullだよ';
}

=> "nullだよ"
```

## 参考

https://wemo.tech/464
[Laravel6]  よくあるエラー４つ

## 注意！
以下の内容は必ずしも「このエラーが出たら、これをすれば解決します！」ということを保証しているわけではありません。
あくまで１つの参考としてお読みください。

## SQLエラー「〇〇カラムはnullを許しません！」

- nullってことはつまり、値が入っていないってこと(前提を確認することは大事)
- まず  `dd($request)` でDB通信の内容を確認する。
- そしたら案の定、input の name属性の指定がタイポしていた、みたいなことがよくある

## 404

Routingを見直す

1. `php artisan route:list` でroutingが正常に設定されているかを確認
1. Apache設定の見直し
    1. 大体Documentroot
    💡 そもそものURL指定は間違ってない？ `localhost/フォルダ名/public/routing` だよ！
        

## バリデーション実装時の403エラー

- Requestのauthorizeメソッドがfalseになってるからだと思うよ
    - false ⇒ trueで解決！

## このRouteはPOSTをサポートしていません

- Routingに記述されてあるものとformのaction指定の記述にズレがあった
kotlin勉強: classとproperty

## 遭遇
```kotlin
class Person(name: String) {
    fun program() = println("$name program")
}
```

`Unresolved reference: name`というエラーが出た

## property
constructorの中で`var`か`val`で定義しないとclassのpropertyにならないのは原因です！なるほど！

```kotlin
class Person(val name: String) {
    fun program() = println("$name program")
}

fun main() {
    val person = Person("Arthur")
    person.program()
}
```

## 確認
```kotlin
package com.example.webviewtest.learn

import kotlin.reflect.full.memberProperties

class Person(name: String) {
//    fun program() = println("Person: $name program")
}

class Person2(val name: String) {
    fun program() = println("Person2: $name program")
}

fun main() {
    val person = Person("Arthur")
    val person2 = Person2("Arthur")
    println(person::class.memberProperties)
    println(person2::class.memberProperties)
}
```

結果↓確かにPersonはpropertyが持ってないことになってます

```kotlin
[]
[val com.example.webviewtest.learn.Person2.name: kotlin.String]
```

## valとvarを使わない場合は
クラスの中でpropertyを定義しないといけない


```kotlin
class Person2(name: String) {
    var name: String = name

    fun work() = println("$name program")
}
```
ソフトウェア・テストの技法 を読んだので、要点と感想

## 読んだ本
[ソフトウェア・テストの技法第2版](https://www.amazon.co.jp/dp/B07SJYG949/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1)

![41IeGuTGutL.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182399/66ace234-3f5c-da7e-0e69-5acb676bab12.jpeg)

1,2,3,4,7章を読みたくてGWからちょくちょく読んでいました。
刺さったところ、要点・メモを書いておきます。感想含むためポエムタグつけときます。

## 1章: 自己診断テスト
- 入力ダイアログから3つの整数を読んで、不等辺三角形・二等辺三角形・正三角形のどれであるかを示すプログラム
- 簡単なプログラムでさえテストは容易でない
- 複雑なプログラムを完全にテストすることは不可能

## 2章: プログラム・テストの心理学と経済学
### 心理学
- テストとは？
    - エラーを見つけるつもりでプログラムを実行する過程
- "プログラムにエラーがないことを証明するため"にテストを書くことがあるが、人間は心理的に失敗に導かれないようなデータを選択する
- 一方で、エラーを見つける確率が高いデータを選んだ方が価値が高いテスト

"プログラムにエラーがないことを証明するため"という定義をすると、達成は不可能。
しかし、"プログラムのエラーを発見する過程"と定義すると、実現性が高いので心理的障壁を壊せる。

### 経済学
全てのエラーを見つけるためのテストは可能か？→否。
ブラックボックステストもホワイトボックステストもどちらも実行不可能。
徹底的な入力テストは、全ての入力可能性のあるテストは無限にある。(前の処理に依存していたらなおさら)
経路テストも天文学的な数値になる。

## 3章: プログラムの検査、ウォークスルー、検討
3章は人的テストについて述べている。
結論言うと、人的テストは手法は非常に有効。
チェックリストや仲間内での検討。ウォークスルー(説明)。


## 4章: テストケースの設計
1. 仕様が入力条件の組み合わせを含んでいる場合は、原因-結果グラフを作る
1. どんな場面でも限界値分析を行う
1. 必要であれば同値分割のテストケースを追加する
1. エラー推測
1. プログラムの論理を調べる

論理の調べ方は以下。
判定条件網羅 > 条件網羅 > 判定条件/条件網羅 > 複数条件網羅

後ろに行くほど完全に近い。けど、量も多くて時間がかかる。

### エラー推測
手順化が難しいが、直感と経験からエラーを推測して、そのエラーを発見するためのテストケースをかける人がいる。
手順はないが、最良の代替案は、プログラムを設計したときに見逃したかもしれない特別なケースをあげること。

### 原因-結果
[原因結果グラフ技法の解説(1)](https://softest.jp/?p=34)


## 7章: デバッグ
### エラーの位置発見の原則
- 考える
- 行き詰まった時は、明日までのばす or 他人に説明する
- デバッグ道具に頼らない
    - 思考の代わりではなく、補助として使う
- 実験は最後の手段

# 全体の感想
- 日本語訳が非常に読みにくい。
- けど書かれている内容は、原理原則なので得るものが多かった。
- 自分の中で言語化されていないものが言語化されていて、要点を再認識できた。
- 逆にいうと既に行動まで出来ているものもあった。
- 原理原則抑えたいのならおすすめすると思う。
- 今回読んでいないものは次の機会に。

以上です~
Reactでreact-queryを利用する。

## React-Queryとは
react-queryは非同期通信時のデータをフェッチするためのライブラリ。サーバの状態を管理し、API等での非同期通信によるデータをキャッシュできる。

![スクリーンショット 2022-05-26 20.56.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599049/751ee85e-7dfe-a705-ffe1-580a931d341f.png)

### ReactーQueryのサンプル実装

成果物の完成イメージ
![スクリーンショット 2022-05-26 21.24.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599049/92e6ab7a-8679-ca79-52d9-ad8f4b0c6f06.png)


```shell: ディレクトリ構成
~/develop/react/react-query-tutorial $ tree src
src
├── App.css
├── App.tsx
├── UseUsers.tsx  ←react-queryの本実装
├── User.tsx
├── index.css
├── index.tsx
├── logo.svg
├── react-app-env.d.ts
├── reportWebVitals.ts
├── setupTests.ts
└── types.ts

0 directories, 11 files
```

```typescript: App.tsx
import { QueryClient, QueryClientProvider } from "react-query";
import Users from "./User";

import "./App.css";

const QUERY_CLIENT = new QueryClient();

function App() {
  return (
    <QueryClientProvider client={QUERY_CLIENT}>
      <div className="app">
        <h1 className="title white">ユーザ一覧</h1>
        <Users />
      </div>
    </QueryClientProvider>
  );
}

export default App;
```

react-queryを利用する場合、`QueryClientProvider`で囲う必要有り。


```typescript: User.tsx
import useUsers from "./UseUsers";
import "./App.css";

const Users: React.FC = () => {
  const { isLoading, users } = useUsers();

  // Loading状態を検知する
  if (isLoading) {
    return <div className="loading">is loading...</div>;
  }

  return (
    <div>
      {!!users?.length &&
        users.map((user) => (
          <p key={user.name} className="user_name">
            {user.name}
          </p>
        ))}
    </div>
  );
};

export default Users;

```

```typescript: UseUsers.tsx
import { useQuery } from "react-query";
import { IUser } from "./types";

const API_URL = "http://localhost:3030/users";

const useUsers = () => {
  const {
    data: users, // 実際の取得データ
    isLoading, // 取得中であるかどうかを検知する。
    error,
  } = useQuery<IUser[]>("users", () =>
    fetch(API_URL).then((res) => res.json())
  );
  return { users, isLoading, error };
};

export default useUsers;
```

```typescript:types.ts
export type IUser = {
  user_id: string
  name: string
  gender: string
}
```

```json:db.json(json-serverで実行)
{
    "users":[
        {
            "user_id":123,
            "name":"kkfactory01",
            "gender":"men"
        },
        {
            "user_id":234,
            "name":"kkfactory02",
            "gender":"women"
        }
    ]
}
```



### 参考
https://react-query.tanstack.com/
Specification of Module XCP, No.412, AUTOSAR R21-11(183) CP

Specification of Module XCP, No.412, 2021-11

https://www.autosar.org/fileadmin/standards/classic/21-11/AUTOSAR_SWS_XCP.pdf


AUTOSAR R21-11記事一覧はこちら。

AUTOSAR 21-11, 160文書読んだ。2022年5月に半分到達。

https://qiita.com/kaizen_nagoya/items/4043e8414f850ce266a4

AUTOSAR R21-11(0) 仕様ダウンロード一覧。単語帳。参考文献資料作成

https://qiita.com/kaizen_nagoya/items/9b3a1b9b8d1e8d7e288e

## 用語(terms)

|Term|Description|
|:--|:--|
|AUTOSAR |AUTomotive Open System ARchitecture
|A2L |File Extension for an ASAM 2MC Language File
|ASAM| Association for Standardization of Automation and Measuring Systems
|BSW |Basic Software
|CAN |Controller Area Network
|CanIf| CAN Interface
|CTO |Command Transfer Object
|DAQ| Data AcQuisition, Data AcQuisition Packet
|DTO |Data Transfer Object
|ECU| Electronic Control Unit
|FrIf| FlexRay Interface
|LPDU |Data Link Layer PDU
|MCD |Measurement Calibration and Diagnostics
|MISRA |Motor Industry Software Reliability Association
|ODT| Object Descriptor Table
|PDU|Protocol Data Unit
|RAM |Random Access Memory
|ROM| Read Only Memory
SchM Schedule Manager
SVN Subversion
SRS Software Requirements Specification
STIM Data Stimulation packet
SW Software
SWS Software Specification
TCP/IP Transfer Control Protocol / Internet Protocol
TS Time Stamp
UDP/IP User Datagram Protocol / Internet Protocol
URL Uniform Resource Locator
XCP Universal Calibration Protocol
XML Extensible Markup Language
ISR Interrupt Service Routine
DET Default Error Tracer (AUTOSAR BSW module)
## 英日単語帳
日本語は仮訳

T.B.D.

## 参考(reference)

Glossary も　参考に入れましょう。
https://www.autosar.org/fileadmin/standards/foundation/21-11/AUTOSAR_TR_Glossary.pdf



[0] Basic Software Module Description Template
AUTOSAR_TPS_BSWModuleDescriptionTemplate.pdf
[1] List of Basic Software Modules
AUTOSAR_TR_BSWModuleList.pdf
[2] AUTOSAR Layered Software Architecture
AUTOSAR_EXP_LayeredSoftwareArchitecture.pdf
[3] General Requirements on Basic Software Modules
AUTOSAR_SRS_BSWGeneral.pdf
[4] Specification of RTE (BSW Scheduler)
AUTOSAR_SWS_RTE.pdf
[5] Specification of ECU Configuration
AUTOSAR_TPS_ECUConfiguration
[6] Specification of Memory Mapping
AUTOSAR_SWS_MemoryMapping.pdf
[7] Specification of FlexRay Interface
AUTOSAR_SWS_FlexRayInterface.pdf
[8] Specification of CAN Interface
AUTOSAR_SWS_CANInterface
[9] Specification of Socket Adaptor
AUTOSAR_SWS_SocketAdaptor
[10] Requirements on XCP Module
AUTOSAR_SRS_XCP.pdf
[11] AUTOSAR OS Specification
AUTOSAR_SWS_OS
[12] General Specification of Basic Software Modules
AUTOSAR_SWS_BSWGeneral.pdf
[13] ASAM XCP – The Universal Measurement and Calibration Protocol:
ASAM_XCP_Part1-Overview - Version 1.1
[14] ASAM XCP – Transport Layer Specification XCP on CAN:
ASAM_XCP_Part3 Transport-Layer-Specification_XCPonCAN - Version 1.2
[15] ASAM XCP – Transport Layer Specification XCP on Ethernet:
ASAM_XCP_Part3-Transport-Layer-Specification_XCPonEthernet
(TCP_IP&UDP_IP) – Version 1.1
[16] ASAM XCP – Transport Layer Specification XCP on FlexRay:
ASAM_XCP_Part3-Transport-Layer-Specification_XCPonFlexRay-Version 1.1
【CLF-C01対策】AWS Well-Architected フレームワーク

公式サイトを見るのが一番ですが、試験対策として、一部分だけ抜粋（これで合格できるのかはわかりません）

https://wa.aws.amazon.com/wellarchitected/2020-07-02T19-33-23/index.ja.html

# フレームワークの 5 本の柱

* 運用上の優秀性
* セキュリティ
* 信頼性
* パフォーマンス効率
* コスト最適化

## 運用上の優秀性

運用上の優秀性 の柱には、 開発をサポートし、ワークロードを効率的に実行し、運用に関する洞察を得て、ビジネス価値をもたらすためのサポートプロセスと手順を継続的に改善する能力。 が含まれます。

### 設計原則

* 運用をコードとして実行する
* 小規模かつ可逆的な変更を頻繁に行う
* 運用手順を定期的に改善する
* 障害を予想する
* 運用上のすべての障害から学ぶ

## セキュリティ

セキュリティの柱には、このセキュリティの柱では、データ、システム、資産を保護して、クラウドテクノロジーを活用し、セキュリティを向上させる機能について説明します。が含まれます。

### 設計原則

* 強力なアイデンティティ基盤の実装
* トレーサビリティの実現
* 全レイヤーでセキュリティを適用する
* セキュリティのベストプラクティスを自動化する
* 伝送中および保管中のデータの保護
* データに人の手を入れない
* セキュリティイベントに備える

## 信頼性

信頼性の柱には、期待されるタイミングで、意図した機能を正確かつ一貫して実行するワークロードの能力。これには、そのライフサイクル全体を通じてワークロードを運用およびテストする機能が含まれます。が含まれます。

### 設計原則

* 障害から自動的に復旧する
* 復旧手順をテストする
* 水平方向にスケールしてワークロード全体の可用性を高める
* キャパシティーを推測することをやめる
* オートメーションで変更を管理する

## パフォーマンス効率

パフォーマンス効率の柱には、 システムの要件を満たすためにコンピューティングリソースを効率的に使用し、要求の変化とテクノロジーの進化に対してもその効率性を維持する能力。 が含まれます。

### 設計原則

* 最新テクノロジーの標準化
* わずか数分でグローバル展開する
* サーバーレスアーキテクチャを使用する
* より頻繁に実験する
* システムに対する精通の程度を考慮する

## コスト最適化

コスト最適化の柱には、最も低い価格でシステムを運用してビジネス価値を実現する能力が含まれます。

### 設計原則

* クラウド財務管理の実装
* 消費モデルを導入
* 全体的な効率を測定する
* 差別化につながらない高負荷の作業に費用をかけるのをやめる
* 費用を分析および属性化する
【Rails】(解決)空のデータベースに対してnil?などのメソッドで条件分岐してもエラーがでる(undefined method `〇〇◯' for nil:NilClass (NoMethodError))



# 環境
- Mac（12.2.1）
  -  MacBook Pro (13-inch, 2020)
  -  2 GHz クアッドコアIntel Core i5
  -  16 GB 3733 MHz LPDDR4X
- ruby (2.7.5)
- rails (7.0.1)
- mysql2 (0.5.3)

# はじめに
```app/controllers/contents_controller.rb
if EgoScore.where(user_id: current_user.id).last.test_result_id.nil?
  @result ="診断していません"
else
  ego_score=EgoScore.where(user_id: current_user.id).last.test_result_id
  @result = TestResult.find(ego_score).egogram_type
```

```app/views/contents/index.html
<%=@result%>
```
上記でエラー

またnil?の部分をpresent?やempty？に変えてもエラー



# 解決した内容

```app/controllers/contents_controller.rb
if EgoScore.where(user_id: current_user.id).present?
  ego_score=EgoScore.where(user_id: current_user.id).last.test_result_id
  @result = "#{TestResult.find(ego_score).egogram_type}タイプ"
else
  @result ="診断していません"
 end
```
【Rails】created_atを２ステップで日本語に設定し、ビューに表示させる方法




## 初めに

今回は２ステップで日本語に設定し、ビューに表示させる方法をまとめました。


#### このような現状にお悩みの方向けの記事です。

・データが作成された時間を日本時間で表示したい方
・ビューに以下の記述をしたところ
```
<%= 表示したいデータの変数名.created_at %>
```

このような時間表示になることでお悩みの方→ 2022-05-26 11:34:06 UTC


## 実装方法

### ①日本時間の表示設定をする

class Application < Rails::Application内に
日本時間に設定する表記を追加します。

```config/application.rb
module LittleArtist
  class Application < Rails::Application
  
    # 日本時間に設定する表記を追加
    config.time_zone = 'Tokyo'
end
```
サーバーを再起動します。
```
rails s
```

### ②ビューの設定


```
 <%= 表示したいデータの変数名.created_at.strftime('%Y/%m/%d %H:%M') %>
```



これで「2022/05/26 20:34」という日本時間の表記に変わっていると思います。
もし変わらない方はもう一度サーバーを再起動してご確認ください。


## まとめ

今回は２ステップで日本語に設定し、ビューに表示させる方法をご紹介しました。
今後も時間を使うことが多いと思いますので、すぐに実装できるようにしていきたいと思います。


ご覧下さりありがとうございました。

## 追記

コメントでこちらの表記よりも、以下の「lメソッド」の書き方の方が便利ということで教えていただきました！
多岐にわたる場所での使用など、場所によって表記を変えたい場合にも有効なようでしたので、追記いたします。

<a href="https://qiita.com/jnchito/items/831654253fb8a958ec25">【初心者向け・動画付き】Railsで日時をフォーマットするときはstrftimeよりも、lメソッドを使おう</a>

貴重な学びをありがとうございました！
Requirements on Module XCP, No.429, AUTOSAR R21-11(180) CP

 Requirements on Module XCP, No.429, 2021-11

https://www.autosar.org/fileadmin/standards/classic/21-11/AUTOSAR_SRS_XCP.pdf


AUTOSAR R21-11記事一覧はこちら。

AUTOSAR 21-11, 160文書読んだ。2022年5月に半分到達。

https://qiita.com/kaizen_nagoya/items/4043e8414f850ce266a4

AUTOSAR R21-11(0) 仕様ダウンロード一覧。単語帳。参考文献資料作成

https://qiita.com/kaizen_nagoya/items/9b3a1b9b8d1e8d7e288e

# 用語(terms)

no

## 英日単語帳
日本語は仮訳

T.B.D.

# 参考(reference)

[1] Software Standardization Template
AUTOSAR_TPS_StandardizationTemplate.pdf