OmniAICreator/Qiita-1.07M huggingface dataset:
AWSにてwebアプリケーション環境をCircleCI Ansibleで自動デプロイしてみた

## 実施の背景

* 知り合いがクラウド案件に従事しており、楽しそうに仕事をしていた。
* ネットワークエンジニアとして働くも、自分もクラウドへの興味が沸く。
* AWSについて2022年3月より学習開始。
* 2022年7月にSAA取得。
* 資格勉強で学んだ知識の落とし込み。
* Ansible、CircleCI、Dockerなどを使用してみたかった。




# 実施概要

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2641225/f5919e9d-1305-7ddc-4879-79179ba69bfa.png)

**作成したコード**
https://github.com/masainaba921/create_app_env_auto.git



**EC2**

HTTP(80ポート)のトラフィックはELB経由のみ許可
VPCエンドポイント経由でS3に静的画像をホスト

**RDS**

MySQL(3306ポート)のトラフィックは、EC2にアサインしたセキュリティグループのみ許可





# 使用技術

**アプリケーション**

Railsを使用したアプリケーション（インフラにコミットしたため最小限構成）
ER図
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2641225/7818a3e0-c65e-036b-2a0c-b29b3c007c61.png)

**CircleCI**

AWS CLI + BashスクリプトでCloudFormationを実行
orbsを用いたAnsibleの実行
Dockerを用いたServerspecの実行


**CloudFormation**

VPC、EC2、ELB、RDS、S3、VPCエンドポイント、IAM

**Ansible**

EC2へアプリケーション用設定を投入
MySQL、Ruby、Nginx、Unicorn

**Serverspec**

ミドルウェア起動確認、アプリケーションレスポンス確認





## 作成中に詰まったところ

**アプリケーションのClone**
* 実現したかったこと
GitHubのプライベートリポジトリからCloneしたかった（今回は断念）

* 断念した理由
AnsibleのコードにGitHubを記載する必要がある
  　セキュリティの観点から、パブリックからクローンした方が安全と判断

* プライベートリポジトリからのClone方法については、下記に記載
https://qiita.com/masainaba921/items/e949c0eb9b39c9f19fe1


**yum install できなくなった問題**
* 原因
EC2が所属しているサブネットのルートテーブルに、yumで参照するリポジトリをVPCエンドポイントを通過する設定が加わる
VPCエンドポイントのポリシーで、自作S3のみを許可していることに気が付いた。

* 対策
参照しているAWSリポジトリを確認
```
sudo yum repolist enabled -v
```
　上記の確認結果をVPCエンドポイントのポリシーにアサイン

**RDSのエンドポイントの事前把握**

* 上記はアカウント×リージョンで決まるとのこと（AWS公式ドキュメント↓）
https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/Overview.DBInstance.html


## 今後の課題
* 別途アーキテクチャ設計などを通して、AWSサービスの理解を深めたい
　今回は自動化がメインになってしまった。
　実務の提案を想定して、どのインスタンスをなぜ選んだといったところも突き詰めていきたい。

* エラーメッセージは、しっかり読み込もう
　多くのエラーに悩まされた。
　振り返るとエラーメッセージの読み込みが浅く、解決に時間を要したことが多くあった。
最速でGoogle Colabで画像生成モデルStable Diffusionを試す。[Notebook付き]

# stable diffusion をcolabで動かす。

最近公開された画像生成モデルをColabでサクッと動かす記事になります。
以下のNotebookに使用コードを載せましたので、Notebook内に必要なものは全て書いてありますが、下記に詳細を書いていきます。



https://colab.research.google.com/gist/white1107/720772025e24f64acdb227c4eaaa7774/stable_diffusion_tutorial.ipynb?authuser=5


# 前準備

## 1 Colabの設定


上記のURLをクリックしてNoteBookを開きます。

このような画面が出たら成功です。


<img width="600",alt="0.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593429/d4b1199c-f9dc-5edb-6df2-1610606286f9.png">

次に、Notebookの設定を画像生成用に設定します。
Editを押すとこのような選択肢が出るので、Notebook settingsを押します。

<img width="700",alt="2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593429/4f5cc483-791f-e779-b38b-af8739fc6c87.png">

最初はHardware acceleratorがNoneになっているので、クリックしGPUに変更します。そしてSaveを選択します。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593429/7a773ad8-f824-046a-9f5f-1250c9481d11.png)


## 2 Huggin Faceのアカウント作成とTokenの作成


URLからHugging Faceにアクセスします。
アカウントを持っていない場合はSign Upで登録してください。E-mailアドレスとアカウント名、名前を要求されるぐらいで比較的簡単に登録できます。


https://huggingface.co/login?next=%2Forganizations%2Fsuggestions%3FemailConfirmation%3Dtrue

登録ができたら、このURLからTokenを作成します。

https://huggingface.co/settings/tokens

New tokenを選択して、read をwriteにして作成してください。このTOKENを

<img width="700",alt="1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593429/694129ab-ce42-dfd5-7516-5aba85a78e61.png">


Notebook内の"HUGGINGFACEのTOKEN"というダブルクオテーション””の間に入れてください。

![Screen Shot 2022-08-24 at 7.19.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593429/9aea0f89-1eaf-67ea-3299-5ab1f77890c8.png)



## 3 ライセンスへの同意

このURLにアクセスし、

https://huggingface.co/CompVis/stable-diffusion-v1-4

画像のAccess repository をクリックします。

<img width="700",alt="1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593429/91a9f967-eaf5-9e2f-d1a0-3e165c76e2b4.png">



これにて前準備は終わりました！

## 4 コードの実行

あとは上から順番に実行していくと画像が生成できます。


実行する場合、このような警告が出ますが、内容はGitHubから読み込まれたものだが実行しますか？というメッセージ文になってます。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593429/042dbf0e-bdba-418b-c6a1-34aa26d60fbd.png)

最終的にこのような宇宙人が馬に乗っている画像が生成されたら成功です。captionの部分を書き換えて楽しんでください。お疲れ様でした。



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593429/7baea2b9-60a7-86b4-df76-e1985e00de38.png)

### 参考にさせていただいたサイト


https://bytexd.com/get-started-with-stable-diffusion-google-colab-for-ai-generated-art/
https://note.com/npaka/n/ndd549d2ce556
バケットポリシーとユーザーポリシー

# S3バケットへのアクセス制限
S3バケットにはアクセス制限を設定できる。
アクセス制限には3つの方法がある。
バケット単位で制限する**バケットポリシー**、IAMユーザー単位で制限する**ユーザーポリシー**、**ACL**(アクセスコントロールリスト)がある。
## バケットポリシー
該当のバケットにアクセスできるユーザーを指定する。
対象ユーザーが多いときに使用。
## ユーザーポリシー
アクセスできるバケットを指定する。
バケットが多いときに使用。
## ACL（アクセスコントロールリスト）
自分以外のほかのAWSアカウントに対して、「読み取り」「書き込み」それぞれの操作を「許可」「拒否」できる一覧表のこと
# アクセス制限の対象と内容
**アクセス制限で設定する項目**
|項目|内容|
|-|-|
|リソース（何に対して）|制限の対象となるバケットやオブジェクト。Amazonリソースネーム（ARN）を使って、対象を識別する|
|アクション（何を）|実際にできる行動のこと。GET（取得）、PUT（配置）、DELETE（削除）など。アクションキーワードを使って指定|
|エフェクト（できるのかできないのか）|設定する可否のこと。許可（Allow）もしくは拒否（Deny）を設定|
|プリンシパル（誰が）|許可もしくは拒否するユーザーやアカウント、サービス|
オブジェクトとバケット

# オブジェクトとバケット
バケットとはWindowsでいうドライブで、オブジェクトとはファイルのようなもの。
**バケットはフォルダではないので、バケット内にさらに子バケットを作ることはできない**。
バケットはAWSアカウント１つに100個まで作れる。
オブジェクトは単にファイルではなく、管理のためにメタデータがついている。
１つのバケットの格納できるオブジェクトの数や容量に制限はない。
S3はオブジェクトストレージなので、フォルダやディレクトリの概念はない。
格納されたオブジェクトは、バケット内に並列に並べられる。
# バケット作成と命名規則
バケット作成後はリージョンやバケット名の変更はできない。
他のS3ユーザーが使用しているバケット名は使用できない。
リージョンを変更したいときは、同じ名前で作成できないので、一度バケットを削除してから新たにバケットを作成する。
## バケットの命名規則
* バケット名の始まりと終わりはアルファベットか数字
* ３文字以上63文字以下
* DNS命名規則に従う必要がある
* IPアドレス形式のバケット名はつけられない
* 大文字やアンダーバーをバケット名に入れることはできない。
一気にディレクトリ / ファイルを作成するLinuxコマンド

## やり方

* ディレクトリ（単一階層）

```bash
mkdir {a,b,c,d,e}
```

結果

```bash
ls
a/ b/ c/ d/ e/
```

* ディレクトリ（複数階層）

```bash
# mkdir -p {a,b,c,d,e}/{e,f}
```

結果

```bash
find .
.
./a
./a/f
./a/e
./c
./c/f
./c/e
./d
./d/f
./d/e
./e
./e/f
./e/e
./b
./b/f
./b/e
```

* ファイル

```bash
touch {a,b,c,d,e}/{e,f}/test
```

結果

```bash
find .
.
./a
./a/f
./a/f/test
./a/e
./a/e/test
./c
./c/f
./c/f/test
./c/e
./c/e/test
./d
./d/f
./d/f/test
./d/e
./d/e/test
./e
./e/f
./e/f/test
./e/e
./e/e/test
./b
./b/f
./b/f/test
./b/e
./b/e/test
```

## 使い道
新しくGitのプロジェクトを作成するときなどに使えるかなと思います。
一通り想定しうるディレクトリを作成して、その下に `.gitkeep` を作成する、など。
【夏休み企画】#IT用語一問一答【毎朝投稿14日目】RPC

# この記事を読むと、、
- 「関連用語」を使って「RPC」を説明できるようになる
- 「RPC」がもっと好きになる(多分)

# 関連用語
IDL / stub / marshalling

[**復習用**] 記事の内容を見る前に上記の言葉で「RPC」を説明してみよう！

# 企画説明
- クラウドって何？って人に聞かれて説明してるけど俺もよく知らないや、、
- ドキュメント読んでみてるけど半分くらい何言ってるか分かんない、、
- 今日の夕飯はナスの炒めものにしよっかな〜、あれ、NASってなんだっけ？

みたいなことが結構あったので、知ったかしていたIT用語を毎日一個ずつちゃんと学んでいこうっていう企画です！

昨日の記事はこちら↓

https://qiita.com/acta/items/e41fda1e2b0738fb8c8c

# RPCとは
RPC = Remote Procedure Protocol = ローカルなサブルーチン呼び出しとほぼ同じコードでのリモート呼び出しを可能にするプロトコル

- 関数とパラメータ(fとx)をメッセージとしてRPCサーバーに渡し、結果(f(x))を受け取るrequest-response型のプロトコル
    - 非同期・同期、どっちのバリエーションもある

- 通常IDLを用いてClient, Server間のOSや言語の違いを吸収する
    - **IDL** = Interface Description Language = インターフェース記述言語

- **stub** = RPCにおいて、Client-Server間の通信やパラメーターの表現形式の変換をしてくれるライブラリ
    - client stub, server stubのどちらも必要
    - パラメータを通信に適した形に変換することを**marshalling**という
    - パラメータを実行可能な形に戻すことをunmarshallingという

## RPCの一例
- JSON-RPC = JSONでencodingするRPC
- SOAP = L6プロトコルにXML, L7プロトコルにHTTPを用いたRPC
    - XML-RPCの後継
- gRPC = Protocols BuffersとHTTP/2を用いたRPC
    - Googleが開発した

# 参考資料
- https://en.wikipedia.org/wiki/Remote_procedure_call
- https://en.wikipedia.org/wiki/Stub_(distributed_computing)
- https://www.techtarget.com/searchapparchitecture/definition/Remote-Procedure-Call-RPC
- https://en.wikipedia.org/wiki/Request%E2%80%93response
- https://developer.mozilla.org/en-US/docs/Glossary/IDL
- https://en.wikipedia.org/wiki/Marshalling_(computer_science)
STM32F767とSWOで「A」を出力して遊ぶ


x mbed os 6.16.0
x Keil Studio


目的
SWOのテスト

![o_con701.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/b3776778-7caa-3281-05b7-082c5733bcb1.jpeg)


![o_con702.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/4b7788e3-ea19-da8d-4b3c-142421d1611d.jpeg)


```c++


//ITM_SendChar_test1_767_1

#include "mbed.h"

void swo_puts(const char *str) {
  while (*str) {
    ITM_SendChar(*str++);
  }//while
}//swo_puts

int main() {

	while(1){
		ITM_SendChar('A');
		wait_us(1000*1000);
	}//while

}//main



```
AWS Amplifyで既存Reactアプリをホストする

#### 既存のReactアプリをAWS Amplifyでホスティングするためのメモ

##### 1．AWS [Amplify ](https://aws.amazon.com/jp/amplify/)にアクセス
AWS Amplifyを使用してアプリをホストするを選択する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653035/7927f74b-bbf3-8724-9ca5-fd827fd6618e.png)


##### 2. Githubを選択、その後は画像の通り進行

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653035/2659c103-d3ed-60db-9198-977819aa20a2.png)

##### 3. AWS AmplifyからGithubへのpermissionについて聞かれるのでAuthorizeする

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653035/eaeaab22-70ca-4f2f-da30-06e64c2543d1.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653035/2cd33b9f-4b05-8045-ebda-541b4f0fd14f.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653035/d8115c5b-0074-0d55-3566-2bea0ec6dd9e.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653035/50dd2e82-7202-ef2f-88c7-ac4539f3070d.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653035/0311ac5c-1e62-063d-18b8-34648d72d159.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653035/a64ea417-5cf9-a666-89e4-2f5ac23406d3.png)

##### 3.保存してデプロイ実行！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653035/61458db2-3165-2bc9-c59f-220faab90c3a.png)

##### 4.Amplifyでプロビジョニングが始まる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653035/5a0bc083-973d-7536-b7d9-c99f7be6eb54.png)


##### 5.しばらくすると検証まで完了
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653035/a7128514-ad5e-3f9c-42bc-8e90e85c09f6.png)

##### 6.アップを確認　OK！！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653035/30c8a2cb-f806-90f7-8c44-a87a7ef1cd19.png)

##### おまけ。githubにプッシュしたら再度デプロイされるか？
pushして、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653035/1bbda70a-d4e5-5375-00ee-cf34af9771a5.png)

再度走っている
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653035/49b49ab5-f775-64cc-07a1-28802490e4df.png)

デプロイされました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653035/09b624cd-3803-4953-2b14-a293cb02d6f4.png)
Amplifyでwebp画像が反映されない？

##### Amplifyにデプロイした画像(webp形式)が読み込まれない・・

Amplifyにデプロイしたアプリ、ボタンにwebp形式画像のアイコンを付加しているのだが表示されない
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653035/68c8927f-6955-dbc0-9366-89d52685c2ca.png)

ローカルで確認、出ている。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653035/51f10592-0b4a-5d8e-4b38-548c223939e0.png)
githubにはプッシュされている

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653035/0d72f005-46e9-0554-1940-d930b55aa197.png)


なんで？と思って調べてみると、Amplifyってwebpサポートしていないんだ。。
https://docs.aws.amazon.com/ja_jp/amplify/latest/userguide/amplify-console-ug.pdf

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653035/e82e5e44-1135-20c4-4bf8-b255104a67b5.png)


しょうがないので、png形式でアップしなおし。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653035/422f0a9f-b393-ba85-0c7a-74cf763252e9.png)

無事表示された。
本日の発掘動画：Linuxデスクトップ環境

　・デスクトップ環境KDEとLinuxと雑多な話99%♪【タコネ研】
　　　https://www.youtube.com/watch?v=zcioUZKuQbg
　・Linuxディストリビューション・デスクトップ環境ってなあに？【めんどうゆっくり】
　　　https://www.youtube.com/watch?v=NqJPOUCjBqI

デスクトップ環境について学ぶ。


------
【情報・工学】青レンの良質解説動画 発掘一覧
　　https://qiita.com/aokiren8/items/965746f13ce27cb65ffa
Creates Spring Boot application runs in Java Servlet container

# On Servlet 3.0 container

If you plan to run your project on Servlet 3.0 container (e.g. Apache Tomcat start from 7.0), it is very easy to convert the project from run in command line to run in a Servlet container.
1. in software project management tool, change generate file format from jar to war, and prevent to append version number to file name
1. include **org.springframework.boot:spring-boot-starter-tomcat** into project's dependency
1. change the class which annotated with @SpringBootApplication, to extend **org.springframework.boot.web.servlet.support.SpringBootServletInitializer**

That's all!

# Reference
1. [Deploy a Spring Boot WAR into a Tomcat Server](https://www.baeldung.com/spring-boot-war-tomcat-deploy)
Risk of user password recovery in leaked application database 

# Introduction

One of the application design practices is, user passwords should not be stored into a database directly. A better way is to hash the password by hash function (e.g. sha1) and store the password hash.

# Potential vulnerability

Below is a sha1 hash. Do you know the original value?

```
21bd12dc183f740ee76f27b78eb39c8ad972a757
```

I thought it was impossible to recover the original value because the hash function is a one way function. But I am **PARTLY** wrong.

There are some hash lookup websites, which store the hash value of commonly used passwords plus word lookup from a dictionary. When I lookup hash above in one of these websites, I got

```
P@ssw0rd
```

This is a commonly used password, used in training material of Microsoft product. When the database of an application is leaked, hackers can use this way (called dictionary lookup) to recover the password of an account using a weak password. Still there is no way to restore strong password.

# Improvement

Try to append a string which is not related to user information to the password before passing to the hash function. But it is useless if the source code of the system is leaked also.
S3を使用する方法

# S3の操作
バケットの作成や各種設定など、基本的なS3の操作はマネジメントコンソールのS3ダッシュボードから行う。
オブジェクト（ファイル）のアップロードもダッシュボードから行える。
しかし、S3の場合は、日常的なファイルのアップロードを毎度マネジメントコンソールにログインしてから行うのは不便なので、
**APIやSDKを利用してアップロードできるようになっている**。
また、AWS Transfer for SFTPによって、SFTP（SSHで暗号化されたファイル転送のプロトコル）でもアクセスできる。
## APIとSDK
APIとはソフトウェアがやり取りするための仕様。
SDKとはある特定のソフトウェアを開発する際に必要なプログラムをまとめた開発ツール。
S3のマネジメントコンソールでできることは全て、APIやSDKで実行可能。
# S3サービスの機能
**S3サービスの用語**
|項目|内容|
|-|-|
|オブジェクト|S3で扱うエンティティの単位。（イメージ）テキストや画像などのファイルのこと|
|バケット|オブジェクトを格納されるコンテナ。全てのオブジェクトはバケットに格納される|
|バケット名|S3のバケットの名前は他のAWSユーザーも含めて、唯一無二の名前に設定する。Webサーバーとして使用する場合はドメイン名をバケット名にする|
|オブジェクトキー|オブジェクトの識別子。全てのオブジェクトは必ず一つのキーを持つ。バケット・オブジェクトキー・バージョンの組み合わせによってオブジェクトを一意に識別する|
|オブジェクトメタデータ|名前と値のセットのこと。オブジェクトのアップロード時に設定できる。オブジェクトキーはS3がファイルを識別するためのデータだが、メタデータは人間がファイルを管理するためのデータ。|
|リージョン|バケットの物理的な保存場所にある地域|
|Amazon S3のデータ整合性モデル|S3では可用性を保つために、データを自動的に複製して保存するが、書き込みのタイムラグによるデータ不整合を防ぐため、データの整合性を保証している。|
|バージョニング|複数のバージョンを保管すること。異なるバージョンは別のオブジェクトとして扱える|
|ログ|バケット・オブジェクト単位でのログを記録。|
|暗号化|S3に保存されたデータを自動的に暗号化|
|アクセス制御|S3バケットに対する権限を設置|
|Webサイトホスティング|S3バケットをWebサイトとして扱う機能|
# S3を使用する流れ
1. AWSにログイン
リージョンを選択し、マネジメントコンソールを開く
S3ダッシュボードを開く
1. バケットを作成
バケット名を設定
1. バケットの設定
Webサーバーとして使用する場合はStatic website hostingの設定
アクセスできるユーザーを設定
1. ファイルをアップロード
マネジメントコンソールや専用ツールから、ファイルをアップ
## オブジェクトとタグ
オブジェクトにはタグを付けられ、このタグはオブジェクトを探すときに使用できる。また、プログラムに渡す設定値として使える。
# S3バケット作成時の注意点
**S3バケットは作成した後に名前やリージョンを変更することはできない**。
Webサーバーとして使用する場合は**バケットの公開やドメイン、匿名アクセスの許可**を決める必要がある。
#5 【 Unity の教科書 】 をマスターするまでの記録

# :star2:2021/08/23 の目標:star2:
① Unity の教科書 を331ページまで進める
⇒ 331ページまで進めることが出来た。

# :bulb:成果:bulb:
<details>
  <summary>🚀シーン間の遷移方法</summary>

</details>

<details>
  <summary>👾バグ修正</summary>

</details>

<details>
  <summary>🏃アニメーションの作成</summary>

</details>

<details>
  <summary>🎲3Dゲームの作り方</summary>

</details>

# 💯振り返り

目標とする範囲は終わらせることができたので良かった。
理解はまだ出来ていないので，理解が深まったら編集していきたいと思う。
記録を続けていく事が途切れないか怖いけれど，今日も書けてよかったと思う。
ストレージクラスとは

# ストレージクラスとは
S3では借りられるストレージの種類が各種用意されている。ストレージ種類のことを**ストレージクラス**と言う。
ストレージクラスは、標準クラスやアクセスパターンに応じて階層（コストが異なる層のこと）を移動できるクラス、
あまりアクセスしないデータに適したクラスなどがあり、使用用途に合わせて選べる。
**バケット**（オブジェクトを格納するコンテナ）単位でなく、
オブジェクト（ファイル）単位でクラスを選択できる。
ストレージクラスの変更は手動でも行えるが、ライフサイクルポリシーを設定すると自動で行える。
# ストレージクラスの種類
## 標準（Standard）
標準は最もスタンダードなストレージクラス。
３つ以上のAZ（アベイラビリティーゾーン）にデータが保存されるため、99.9%の可用性（システムが稼働し続けること）が保証されている。
データの取り出しに料金はかからず、最小キャパシティ（最小値）料金なし、日割り計算なのでシンプルで使いやすい。
## Intelligent-Tiering（IT）
S3 Intelligent-Tieringでは、高頻度・低頻度それぞれに最適化された2つの階層にオブジェクト（ファイル）を保存する。
どちらに保存されるかは、オブジェクトごとにモニタリングされ、その結果に応じて自動的に稼働される。
このクラスでは取り出し料金がかからない。またアクセス階層間の移動にも料金がかからない。
**よく使うファイルと使わないフィイルが混在していて、頻度が変わるような使い方をするときにコストを抑えられる**
## 低頻度アクセス（IA）
標準クラスに比べ、保存料金が安価に設定されている代わりに、アクセス料金が若干高く設定されている。
**アクセス頻度は低いものの容量の多いデータなどの適している**。
また、低頻度アクセスの中にも２種類のストレージクラスがあり、
**標準-低頻度アクセス**（Standard-IA）と**１ゾーン-低頻度アクセス**(One Zone-IA)がある。
この２つでは保存に使用されているAZの数が違う。
Standard-IAは少なくとも3つ以上のAZに保存されるが、One Zone-IAは1箇所のみ。
そのため、その地域に物理的なトラブルが起きると、データが失われる可能性がある。
## 低冗長化ストレージ（RRS）
低冗長化ストレージ（RRS）は、**正確にはストレージクラスではなく**、
そのオプションという扱いですが、１種類しかないため、実質はストレージクラスの１つと考えていい。
標準ストレージに比べて、冗長化のレベルを下げることで、低価格での提供を実現している。
保存されるAZは1箇所なので、データが失われる可能性がある。
## S3 Glacier/S3 Glacier Deep Archive
Clacierはデータアーカイブ、及び長期のバックアップを意識して作られたストレージクラス。
他のクラスと同じ99.999999999%(イレブンナイン)の耐久性ながら低価格なので、大量のデータを低コストで保存することができる。
データは「ボールド」というコンテナに格納される。そのため、保存したデータを読む場合は、ほかのS3バケットへの取り出し操作が必要。
基本的には一部データだけでなく、丸ごとデータを取り出す。しかし、Glacier上のデータと取り出し先のデータ両方に保存料金がかかる。
# ストレージクラスの基本的な違い(RRSを除く)
|ストレージクラス|Standard|IT|Standard-IA|One Zone-IA|Glacier|Glacier Deep Archive|
|-|-|-|-|-|-|-|
|可用性|99.99%|99.9%|99.9%|99.5%|99.99%|99.99%|
|保存されるAZ|3AZ以上|3AZ以上|3AZ以上|**1AZ**|3AZ以上|3AZ以上|
|データの取り出し費用|なし|なし|**あり**|**あり**|**あり**|**あり**|
|モニタリング費用|なし|なし|**あり**|なし|なし|なし|
|オートメーション費用|なし|なし|**あり**|なし|なし|なし|
Nuxt.jsでロードバランサーを使ってスクリプトが404になっちゃう場合の回避策

Nuxt.jsをサーバー上でビルドするような環境においてSPAで使ってしまうと、複数サーバー構成でロードバランサーを使いたいとなった場合に読み込みスクリプトが404になってしまう場合があります。
これはNuxt.jsに限った話ではないですが、例えば以下のように`/login`のhtmlに書かれた後続のjsファイルを読み込む際にロードバランサーで振り分けられると、読み込み先サーバーにjsファイルが存在しない場合に404エラーとなってしまいます。

![スクリーンショット 2022-08-26 11.51.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144550/473a13d4-0e83-ba7a-7d00-0fff11e499e4.png)

### 回避策
ロードバランサーの効果は薄まってしまいますが、スティッキーセッションを設定することで404エラーを回避することができます。

- スティッキーセッションを設定
![スクリーンショット 2022-08-24 1.30.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144550/a44e847c-64a4-166c-f8b0-58316e152c53.png)

- 404エラーが解消される
![スクリーンショット 2022-08-26 11.52.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144550/dbc23cf3-a5b9-dbf3-92ce-ccb33ad2e045.png)


上記はあくまで回避策のひとつですがデメリットもあるため、デプロイ先変更（S3等）やデプロイ方式見直し、SSRへの変更など他の策も検討してみるのが良いかと思います。
それでは。
Amazon S3とは

# Amazon S3とは
**Amazon Simple Storage Service**(Amazon S3)はインテリジェントな**オブジェクトストレージサービス**
オブジェクトストレージとは、データをオブジェクト単位で管理する形式を指す。
Webサーバーや社内ファイルサーバーのように、インターネット上にデータを保存する場所が借りられる。
容量制限ないので、将来を見越して借りる必要はない。
S3の特徴は、**多機能であること**。誰でも簡単に扱えるようにさまざま機能がある。
**Webサーバー機能とクエリ機能**が代表的な機能として挙げられる。
# 堅牢でインテリジェントなストレージサービス
S3は多彩な機能を備えてるだけでなく使いやすく堅牢であることが大きな特徴
**S3の特徴**
* スケーラビリティ
EC2と同じくスケールアップ・ダウンがしやすくなっている。
使用場面に応じたストレージクラスが複数用意されていて、
ライフサイクルポリシーを使用すれば自動的に移行できる。
* 可用性・耐久性
99.999999999%(イレブンナイン)のデータの耐久性があり、障害やエラー、脅威に対して強い。
S3オブジェクトは最低３つのアベイラビリティゾーンに自動的に複製し保存される。
そのため、どこか一つに障害があっても使い続けられる
* 信頼性
暗号化機能とアクセス管理ツールがあり、攻撃から守りやすい。
各コンプライアンスに適合していて、監査機能が充実している。
* 豊富な管理機能
ストレージクラス分析、ライフサイクルポリシーなどをはじめとした各種管理機能が用意されている
これらを使えば、実際の使用方法にフィットしたストレージクラスの選択ができる
* インテリジェントな機能
S3 Select というデータのクエリを実行する機能やサービスがある。
他にAmazon Athane、Amazon Redshifu Spectrumなどの分析サービスとの互換性があり、
Amazon Lambdaとの連携も可能。
# Amazon　S3の料金体系
S3の料金は**保存している容量**と**転送量**に基づいて従量課金される
S3の料金 = **保存料金** + **転送量**
## 保存容量
S3に保存した容量に対してかかる料金
ストレージクラスによって日割り、30日単位、90日単位、180単位の場合などがある
ストレージクラスによって最小キャパシティー料金が設定されていて、そのサイズに満たなくても最低料金がかかる。
## 転送量
S3からファイルを取り出したり、命令を送ったりするときにかかる料金
取得のリクエストや設置のリクエストに対して１GB単位で課金される。
# 転送量の考え方
転送量を考える上で重要なのが、**リクエストとアップロードとダウンロード**
## 取得のリクエスト(GET)とダウンロード
取得のリクエスト（GET）とは「このファイルが欲しい」「このページが見たい」とサーバーに送る命令のこと。
そしてストレージからクライアント側にファイルが送られることをダウンロードという。
## 設置のリクエスト（PUT）とアップロード
設置のリクエスト（PUT）は「このファイルを置きます」とサーバーにファイルを送る命令のこと。
ファイルをサーバーに転送することをアップロードという。
【Ruby】Railsでリクエストのバリデーションを行うライブラリ`rails_param`

## 概要
Railsでリクエストのバリデーションを行う場合、[Rails基礎　ストロングパラメータとバリデーション](https://hpsuzucat.hatenablog.com/entry/2020/10/24/224143)の記事にある通り、ApplicationRecordの機能を使用する方法などが挙げられます。もちろん、この方法でも全然良いのですが、ApplicationRecordのモデルに通す前に、controllerでバリデーションしたい時もあるなと感じました。
何かないかなと調べてみた結果、`rails_param`というライブラリが良さげだったので、今回少し紹介します。

## 機能など
[nicolasblanco/rails_param](https://github.com/nicolasblanco/rails_param)に、ライブラリのReadmeがあります。パラメータの、型指定や、必須チェック、最小値・最大値など基本的なチェックは出来そうです。また、項目毎にエラーのメッセージもカスタムで設定できます。

## 実装サンプル
以下はAPIで、文字列の必須・ブランクチェックを、controllerに実装したサンプルです。
必須チェックでエラーの場合は、`Parameter sample_word is required`のようなメッセージをデフォルトで返してくれます。

```ruby
class SampleController < ApplicationController

  def validate_sample
    # バリデーションの設定
    param! :sample_word, String, required: true, blank: false
    
    puts(params[:sample_word])
    render status: :ok
  # バリデーションNGの場合
  rescue InvalidParameterError => e
    render status: :bad_request, json: { message: e }
  rescue StandardError => e
    render status: :internal_server_error, json: { message: e }
  end
end
```
BigQueryでネストしたフィールドに検索かける方法

FirebaseAnalyticsをエクスポートしたときなどに遭遇するネストしたフィールドを検索対象したい場合はSTRUCTを使って展開してあげればできます。

こういうやつです↓
![スクリーンショット 2022-08-24 1.07.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144550/c22089b2-0848-c0b8-5f00-5b9e0619150f.png)

### クエリ

```sql
SELECT * FROM (
  SELECT 
  (
    SELECT AS STRUCT
      ANY_VALUE(CASE WHEN key = 'ga_session_id' THEN value.int_value END) as ga_session_id,
      ANY_VALUE(CASE WHEN key = 'session_engaged' THEN value.string_value END) as session_engaged,
    FROM UNNEST(event_params)
  ).*
  FROM `dataset.events_20220822`
)
WHERE ga_session_id = 1661121678
AND session_engaged = '0';
```

### 結果

![スクリーンショット 2022-08-24 1.12.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144550/e3c69124-c6f7-9289-4b6a-0eef2b3bdc4c.png)

これでevent_paramsやuser_propertiesを拡張しても複数の条件指定などができるかと思います。
それでは。
DOSコマンドで二重引用符の環境変数展開の挙動

DOSコマンド(DOSプロンプト)で二重引用符の中に`"%PATH%"`などの文字列があると、環境変数が展開されてしまいます。環境変数を展開せず、正しく`%PATH%`という文字列を表すにはどうしたら良いか、かなり悩んだので答えを書きます。

# 問題の詳細

以下のように書くと、環境変数PATHの値が展開されて表示されます。

```
echo %PATH%
echo "%PATH%"
```

DOSコマンドで`%`をエスケープするには、`^`を使えば良いとのことです。

```
echo ^%PATH^%
```

ただし、二重引用符で括りたい場合、これではだめです。以下を実行すると、単純に`"^%PATH^%"`と表示されてしまいます。これは二重引用符の中ではエスケープ記号の`^`が効力を失ってしまうからです。

```
rem 失敗の例
echo "^%PATH^%"
```

そこで、いろいろ試した結果以下のように書くのが正解です。`%`を`"^%"`に置換します。echoの表示結果は`""%"PATH"%""`となりますが、保存先のファイルにこの置換ルールを指定すると、正しく`%`をエスケープできます。

```
rem --- 正解 ---
echo ""^%"PATH"^%""

rem --- 保存先ファイルに指定してみる ---
echo "" > ""^%"PATH"^%".txt"
dir *.txt
```

上記をDOSプロンプトで実行すると、無事に`%PATH%.txt`というファイルができているのを確認できます。
はっきり言って、パズルです。。。
需要に合わせてEC2の台数を増減「AutoScaling」

# Auto Scalingとは
**Auto Scaling**（オートスケーリング）とは、
サーバへのアクセス状態によってサーバーの台数を増やしたり減らしたりする機能
EC2以外のサービスに対応したAuto Scalingもある
AWSではEC2 Auto Scaling を単体で使用するばかりでなく、
CloudWatchからサーバーの負荷情報（CPU負荷、ネットワーク通信量など）
を使ってスケーリングに役立てることがある。
# 監視とインスタンス数の決定
Auto Scalingを開始するためには**AutoScalingグループ**(インスタンスの集合)を作成し、
グループにインスタンス（サーバー）の最小数と最大数を設定する。その中でインスタンスの数が増減する。
Auto Scalingグループには起動する際に必要なAMIやキーペア、セキュリティグループなどを設定する。
## インスタンスの増減の３つの方法
* EC2インスタンスが停止した場合に切り離して新しいEC2インスタンスを作る
* スケジューリングに基づきスケーリング
* CPUやネットワークの負荷を参照し、閾値を超えた時にインスタンスの数を自動的に増減

**Auto Scalingの料金は無料**
ただし、CloudWatchを使用する場合、モニタリングに関する料金はかかる

# 余談
EC2と連携することが多いAWSのサービス
|項目|内容|
|-|-|
|Amazon S3|インターネット用のストレージサービス|
|Amazon RDS|リレーショナルデータベースサービス|
|Amazon CloudWatch|モニタリング・管理サービス|
|Amazon Route 53|DNSサービス|
|Amazon VPC|仮想プライベートクラウド|
PukiWikiにGoogle Adsenseを導入

## 概要
前回の記事
https://qiita.com/Unirenkon/items/ea292803557c47c17284
シリーズ化して書いてましたが、個々の内容をタイトルにして書いて言ったほうがわかりやすいと思ったので、
今回はPukiWikiにGoogle Adsenseの申請を行うまでを本記事にて紹介します。

## Google AdSenseとは
Google AdSenseとは、Googleの提供するコンテンツマッチ型広告配信サービス。
運営するブログやサイトなどに設置することで、サイトのユーザーのニーズに合わせて、広告が自動的に配信される仕組み。
QiitaでもTOP右上に広告が出ていることがあると思うが、ああいう広告を自分のサイトに貼り付けて、ユーザーにクリックされれ広告収入を得ることができる。

## 手順
1. [Google Adsense](https://www.google.co.jp/adsense/?sourceid=aso&subid=jp-hp-wsafs&hl=ja)にアクセスし、アカウント登録をする。
私の場合は先にGoogle Site Consoleという検索パフォーマンスを調べることのできるサービスに登録していたので、ここはGoogleアカウントにログインするだけで終わりましたが、初回では下記の情報を入力する必要があるそうです。

* ウェブサイトのURL
* メールアドレス

この後はGoogle Adsenseトップページの下記のタスクに従って行います。
![スクリーンショット 2022-08-24 0.53.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296171/1c91e0e4-5a40-9091-1b97-87faf8e87d49.png)

※この記事は申請完了後になっているので、全て完了している画面となっています。
また、2~4の手順はPukiwikiに限らずどんなサイトでも共通なので、この記事上では詳しいことは省きます。
参考にさせていただいたサイト様などを参照すれば、詳しい手順を確認できます。l

2.個人情報を登録する

登録には住所や氏名などの個人情報が必要になります。
フォームに従い入力します。

3.電話認証をする
電話番号を入力し、お手持ちのスマートフォンのSMSに届いた番号を入力し認証を完了します。

4.広告設定をする
こちらは自動広告設定にしておけば、Googleが勝手に広告を貼れそうなところに貼ってくれるそうなので、今回は自動にします。

5.サイトにコードを埋め込む
ドメイン名ディレクトリ配下のpublic_html>skin>pukiwiki.skin.phpの73行目あたりに< head >タグがあります。
その下を辿ってみると、数行先に< /head >タグがあると思います。
この< head >< /head >の間の任意の場所に、Adsenseリンクを貼り付けます。

```
<head>
 <?php echo $meta_content_type ?>
 <meta http-equiv="content-style-type" content="text/css" />
<?php if ($nofollow || ! $is_read)  { ?> <meta name="robots" content="NOINDEX,NOFOLLOW" /><?php } ?>
<?php if (PKWK_ALLOW_JAVASCRIPT && isset($javascript)) { ?> <meta http-equiv="Content-Script-Type" content="text/javascript" /><?php } ?>

 <title><?php echo $title ?> - <?php echo $page_title ?></title>

 <link rel="SHORTCUT ICON" href="<?php echo $image['favicon'] ?>" />
 <link rel="stylesheet" type="text/css" media="screen" href="<?php echo SKIN_DIR ?>pukiwiki.css.php?charset=<?php echo $css_charset ?>" charset="<?php echo $css_charset ?>" />
 <link rel="stylesheet" type="text/css" media="print"  href="<?php echo SKIN_DIR ?>pukiwiki.css.php?charset=<?php echo $css_charset ?>&amp;media=print" charset="<?php echo $css_charset ?>" />
 <link rel="alternate" type="application/rss+xml" title="RSS" href="<?php echo $link['rss'] ?>" /><?php // RSS auto-discovery ?>

//ここに貼り付ける

<?php echo $head_tag ?>
</head>
```

貼り付けたら審査をリクエストをクリックし、申請は完了です。
申請には２週間ほど時間がかかるそうなので、気長に待ちたいと思います。

## 参考にさせていただいたサイト
https://lolipop.jp/media/google-adsense/
zipファイルの中身をヘッダ・フッタ無しで表示する（unzip -Z1）

ファイル名だけ表示：
```
$ unzip -Z1 a.zip
hoge.rb
hoge.js
prod.json
```

パーミッション・タイムスタンプ・サイズ等も表示：
```
$ unzip -Z a.zip
Archive:  a.zip
Zip file size: 4163 bytes, number of entries: 3
-rw-rw-r--  3.0 unx      118 tx defN 22-Aug-21 02:03 hoge.rb
-rw-rw-r--  3.0 unx      258 tx defN 22-Aug-21 02:29 hoge.js
-rw-rw-r--  3.0 unx    15666 tx defN 22-Aug-23 15:44 prod.json
3 files, 16042 bytes uncompressed, 3711 bytes compressed:  76.9%
```

パーミッション等を表示しつつヘッダ・フッタを抑制することはできないらしい。
colaboratoryでstr改行内の改行コード(\n)が削除できないときの対処法

**`str.replace('\n','')`や`str.strip()`などで改行コードが削除できると思っていましたがうまくいかず困りました。**

使い方が違う可能性もありますが、よく知られているやり方でやってうまくいかなかったので書き記しておこうと思います。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173847/cc06ac96-676c-1ab2-17ca-33b6e7419c89.png)
(↑↑なぜ削除してくれないのか？)

---

原因は不明ですが、一度改行コードでsplitし、再結合させれば解決できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173847/a99f71c7-2e10-cad6-b9c2-fdaf96bf187f.png)

```.py
    out = ''.join(str.split("\n"))
```

同じ症状に困った方のお役に立てば幸いです。また、原因が分かる方などいらっしゃいましたらコメントなどお願いいたします。
GitHubを使いながらGitに慣れる

<<注>>GitやGitHubについて学んだことをアウトプット
<<注>>まだまだ加筆中(20220913現在)
# はじめてGitを使う前に
## Gitとは？
　多くの書籍やサイトで、Gitは<b>「ソースコードの変更履歴を記録・保管するためのバージョン管理システム」</b>です、と書かれています。
<br>
たとえば、こんな時に便利！
・昨日までは正常に作動していたファイルが、今日作業したあとで原因不明のエラーを吐き始めた。昨日までの状態にロールバックしたい時
・複数人から構成されるチームで分業してコーディングしている現場で、それぞれが書いたコードを共有したい時。また、チームメンバーが書いたコードを引き継いで編集したい時

## GitHubとは？
　前述のように<b>「複数人のチームでプログラミングをする際のチーム開発をするためのGitを活用したwebサービス」</b>です。


# 実際にGitとGitHubを使ってみよう！
## Gitのインストール
・Gitを使うために、Gitの環境構築
・WindowsとMacによってオペレーションを変える

・Gitのコード一覧
git status  gitの状態を確認する
git init レポジトリを作成



# 参考文献
・<b>[ProGit](https://git-scm.com/book/ja/v2)</b> 
　Gitがオフィシャルに公開しているマニュアルの日本語版。リンク先から詳しい説明へ飛べる上に、pdf版epub版がリリースされています。

https://git-scm.com/book/ja/v2

<br>

・<b>[サル先生のGit入門](https://backlog.com/ja/git-tutorial/)</b>
　Git初学者が必ず読んでいるチュートリアルサイトです。私も大学の研究で初めてGitを使うことになったときに、参考になりました。

https://backlog.com/ja/git-tutorial/

<br>

・<b>[【超入門】初心者のためのGitとGitHubの使い方](https://tech-blog.rakus.co.jp/entry/20200529/git#GitHub%E3%81%A8%E3%81%AF)</b>
 Gitの概念からインストール、使い方まで網羅的に紹介されているブログです。

https://tech-blog.rakus.co.jp/entry/20200529/git#GitHub%E3%81%A8%E3%81%AF
classnamesほど高機能じゃなくてもいいんだよなぁ～の場合の書き方メモ

## classnames
こちらの[classnames](https://github.com/JedWatson/classnames)はREADMEにある通り、結構いろんな書き方ができるので便利です。

便利だな～と思ってつかっているのですが、ちょこっとクラス名を切り替えるくらいしかしない自分にとっては「stringの配列で指定できればそれでいいのだよな…」
と思っていました。

最低限

- 配列でクラス名をいくつか指定したら半スぺ区切りの文字列を返してくれる
- 要素が配列になっていたら均してくれる(2～3くらい　それ以上は型ではじく)
- クラス名がミスって被っていたとしても重複を除いてくれる
- 空文字列を返すと除外してくれる

こんくらいあればよくて、ちょっとサポートしてくれるだけで充分なんだよなぁと思っていたのでメモ代わりにコードを残します。

オブジェクトでプロパティにクラス名を入れてvalueにbooleanをいれて…
がやりたい人はこの記事の対象ではありません。

例はSvelte。.svelteにするとハイライトがきかないので分けて書きます。

### &lt;script lang="ts"&gt;部分

``` ts
	const current = true;
	let isAnimated = true;
	$: animatedClass = isAnimated ? 'animatedClass' : '';
	type Allow = (string | (string | string[])[])[];
	const classNames = (stringArray: Allow) => [...new Set(stringArray.flat(2).filter(c => c))].join(' ');
```

``` jsx
<p
	class={classNames([
		'defaultClass',
		'',
		['test', true ? ['test1', true ? 'test2' : 'test3'] : 'test4'],
		'test',
		`${animatedClass}`,
		current ? 'is-current' : ''
	])}
>
	class="defaultClass test test1 test2 animatedClass is-current"になる
    'test2'の部分をさらに配列にすると型エラーになる
</p>
<button on:click={() => (isAnimated = !isAnimated)}>toggleAnimatedClass</button>
```

## Tips
そういえばSvelteはclass名部分などで

``` jsx
<p class={`bg-${colorName}`}>test</p>
```
みたいにしなくても
``` jsx
<p class="bg-{colorName}">test</p>
```
でいけるの知ってました？僕はこの前知りました。
ちょっと短く書けますね。
【初心者向け】Obsidianを使ってみたい人が、macの基本的なセットアップから始めて、macの基本機能を含めて使えるようになるための手順メモ


## INDEX
---

1. macのセットアップ
2. mac利用に必要なアカウント整備
3. Android端末へのデータ転送・共有
4. obsidianの基本的な機能について

---

#### 1.macのセットアップ

- 新規ユーザを作成
- 新規ユーザに管理者権限を付与
- サファリを起動し、Google Chromeをインストール
- Google Chromeを起動し、Google日本語入力をインストール

---

#### 2.mac利用に必要なアカウント整備

- Googleアカウントを取得
  　データ連携に必要なGoogleDriveの準備
  　コミュニケーションに必要なGmail / GoogleChatの準備
  　Google Chromeの基本機能・情報保管のため
- AppleIDを取得
      macの純正アプリインストール時に使用

---

#### 3.Android端末へのデータ転送・共有

Android端末：
- Play StoreからObsidianをダウンロード
- ファイルの管理者権限を付与

mac ：
- obsidianフォルダをGoogleドライブにコピー


Android端末：
- GoogleドライブからAndroidのローカルドライブにコピー
- ObsidianアプリからOpenFolder As Voultでフォルダをオープン
- アクセス許可
- Obsidianから作成した情報が参照できること
- Obsidianで新規のファイル作成ができること

---

#### 4.obsidianの基本機能について : #manual 

##### ツールの理解：

1. メモ帳の一種。
2. 作成したメモをグラフビューの形で見える化できる。
3. 様々なメモをグループ化、タグ付け、色付けをしていくことで属性ごとの情報を強化したり、現状の把握をしたり、自分なりの「もう一つの脳みそ」「もう一つの宇宙」を作っていくことができる。
4. 一般的なメモ帳に比べ、構造の理解、目的付けなどが難解なため、万人向けではないが色々なものごとを関連付けて考えたい人、思考整理が好きな人には向いている。


#### 基本のショートカット(最低限これだけ覚えとけば使える)
---
- メモの新規作成 : cmd + N
- グラフビューの参照： cmd + G
- ファイルオープン：cmd + O
- キーワード検索：cmd + shift + F
---
サーバーのデータをバックアップ「スナップショット」

# スナップショットとは
**スナップショット**(snapshot)とは、ある時点でサーバーのディスク状態を丸ごと保存したファイルやフォルダなどの集合
データやソフトウェアだけでなくOSや設定情報などの全て含む。
スナップショットの用途は、ソフトウェアやOSの更新時に何かあった時にすぐ戻せるようにバックアップとして取ることが多いですが、
自作のAMI（Amazon Machine Image）を使うためにも使われる

AWSではAmazon EBS（Elastic Block Store）ボリュームのデータをスナップショットとして保存できる。
ただ、１度目は丸ごと保存しますが、２度目以降は差分で保存する。
# EBSスナップショット作成の使い方
スナップショットはマネージドコンソールからボリューム単位（ストレージ丸ごと）を選択し作成。
この作成したスナップショットを元にEBSボリュームを作れば、新しいボリュームは元となったボリュームのコピーになる
AMIを作成したい場合はスナップショットから作成する
データライフサイクルマネージャー(Amazon DLM)を使用するとスナップショットの差分生成・削除を自動化できる。
スナップショットを定期的に作成すると、サーバーが壊れた時のリスク対応になる
# 余談
スナップショットの保存先はAmazon S3。
スナップショットのファイルをユーザーが自由にダウンロードできるわけでない。
ユーザーがS3を使用するときの領域とは別の見ることができない場所に保存される。
話題の Stable DiffusionをColabで作ってみた！

今話題のAI画像生成の簡易的なソースを作りましたので、試してみたい方は是非使ってみてください！

# 実行環境
Google colab
Python 3.7.13
diffusers 0.2.4

# 前提条件
Googleのアカウントがある
huggingfaceのアカウントがある


# 環境構築手順
1. ライセンスの確認
モデルカードにアクセスしてライセンスを確認します。
https://huggingface.co/CompVis/stable-diffusion-v1-4
![CompVis_stable-diffusion-v1-4 · Hugging Face - Google Chrome 2022_08_23 23_01_41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396776/234a7eac-b69d-b31a-da5f-8a4968424d2d.png)

2. アクセストークン発行
https://huggingface.co/settings/tokens
![CompVis_stable-diffusion-v1-4 · Hugging Face - Google Chrome 2022_08_23 23_05_23.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396776/d0b1045b-1028-36f1-6b18-975c9776d8cd.jpeg)

3. Colabハードウェアアクセラレータの変更
通常NoneになっているハードウェアアクセラレータをGPUに変更
Colab上部タブ「編集」押下
↓
ノートブックの編集を押下
↓
ハードウェアアクセラレータのプルダウンでGPUを選択

# Colabコマンド

```python
!pip install diffusers==0.2.4 transformers scipy ftfy
```

```python
import torch
from torch import autocast
from diffusers import StableDiffusionPipeline

model_id = "CompVis/stable-diffusion-v1-4"
device = "cuda"
YOUR_TOKEN="<HugginFace Hubのトークン>"

pipe = StableDiffusionPipeline.from_pretrained(model_id, use_auth_token=YOUR_TOKEN)

# お題をpromptに記入
prompt = "日本 城 合戦"
image = pipe(prompt)["sample"][0]

# 保存名を記載
image.save(f"japanese_castle.png")
```

実行すると下記の写真のように処理が始まり、完了するまで放置する。

![StableDiffusion.ipynb - Colaboratory - Google Chrome 2022_08_23 23_14_44 (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396776/4ecb1f2c-ac08-699d-a7f2-c06ad30ed344.png)

上記のキーワードでできた画像がこちら
![japanese_castle.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396776/20b538b0-8c1e-d929-f4c3-224b0058b0b4.png)

お城というかお寺ができましたね！
jest で uuid がインポートされているファイルを読み込むとエラーになってしまう。


## 環境
- nodejs: 14.17.6
- uuid: 8.3.2
- nextJs: 12.1.0
- typeScript: 4.6.2

## エラー内容
uuid パッケージが ECMAScript　に対応していないのが原因かな？？
```sh
  ● Test suite failed to run

    Jest encountered an unexpected token

    Jest failed to parse a file. This happens e.g. when your code or its dependencies use non-standard JavaScript syntax, or when Jest is not configured to support such syntax.

    Out of the box Jest supports Babel, which will be used to transform your files into valid JS based on your Babel configuration.

    By default "node_modules" folder is ignored by transformers.

    Here's what you can do:
     • If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/ecmascript-modules for how to enable it.
     • If you are trying to use TypeScript, see https://jestjs.io/docs/getting-started#using-typescript
     • To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
     • If you need a custom transformation specify a "transform" option in your config.
     • If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.

    You'll find more details and examples of these config options in the docs:
    https://jestjs.io/docs/configuration
    For information about custom transformations, see:
    https://jestjs.io/docs/code-transformation

    Details:

    /........./node_modules/uuid/dist/esm-browser/index.js:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){export { default as v1 } from './v1.js';
                                                                                      ^^^^^^

    SyntaxError: Unexpected token 'export'

      1 | import _ from 'lodash';
      2 | import moment from 'moment';
    > 3 | import { v4 as uuidv4 } from 'uuid';
        |                                    ^
```

## 解決
```jest.config.js
const customJestConfig = {
  // Add more setup options before each test is run
  // setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
  // if using TypeScript with a baseUrl set to the root directory then you need the below for alias' to work
  moduleDirectories: ['node_modules', './src'],
  testEnvironment: 'jest-environment-jsdom',
  moduleFileExtensions: [
    'ts',
    'tsx',
    'js',
    'mjs',
    'cjs',
    'jsx',
    'json',
    'node',
  ],
  testMatch: ['**/__tests__/**/*.[jt]s?(x)', '**/src/**/*.test.[jt]s?(x)'],
  verbose: true,
  moduleNameMapper: {
    '^@/(.*)$': '<rootDir>/src/$1',
    uuid: require.resolve('uuid'),  // <- 追加
  },
};
```

## 追記
uuid 9系では、この問題が解決されるっぽいです。
https://github.com/uuidjs/uuid/issues/451#issuecomment-1206284480

## 参考
https://stackoverflow.com/questions/73203367/jest-syntaxerror-unexpected-token-export-with-uuid-library
【numpy】np.ix_を使った任意の格子点の要素を抜き出して配列を作成する方法

# 概要
numpyを使っていると任意の格子点の要素を抜き出して配列を作りたい場合がある。そんなときに便利なのが、[``numpy.ix_``](https://numpy.org/doc/stable/reference/generated/numpy.ix_.html)である。この``numpy.ix_``を使った方法を紹介する。

# 実装
Google Colabで作成した本記事のコードは、[こちら](https://colab.research.google.com/drive/1i23hqWnZOf644pAzzD2rGsOkvAfxyxKU?usp=sharing)にあります。

``np.ix_``の入力は、1次元のシーケンスで各シーケンスは整数型またはbool型である必要がある。bool型シーケンスの場合は、``np.nonzero(boolean_sequence)``に等しく、つまり、シーケンスの``True``に対応したindexの格子点が抜きだされる。
``np.ix_``の出力は、N次元の配列で、Nは入力シーケンスの数に対応する。
使い方は公式ドキュメントによると
>Using ix_ one can quickly construct index arrays that will index the cross product. a[np.ix_([1,3],[2,5])] returns the array [[a[1,2] a[1,5]], [a[3,2] a[3,5]]].
>NumPy numpy.ix_ version 1.23より引用

と書かれていて、外積をとった配列のindexのリストを返すことで、任意の格子点のindexの配列を作ることができる。

## 整数型の例
視覚的にも分かりやすくするために、抜き出したindexを赤色でプロットし2次元ヒートマップに表示する。左図が``array``で、右図が左図の赤色のプロットしたindexを抜き出して配列にした``mesh_aray``である。
```Python:整数型の例
import numpy as np
import matplotlib.pyplot as plt

array = np.arange(6*10).reshape(6, 10)
x = [0, 1, 3, 5, 9]
y = [0, 1, 4, 5]
mesh_array = array[np.ix_(y, x)]

print('array:\n', array)
print('mesh_array:\n', mesh_array)

"""2次元ヒートマップで表示"""
fig, (ax1, ax2) = plt.subplots(ncols=2, figsize=(10, 12))

ax1.imshow(array, vmin=np.min(array), vmax=np.max(array))
ax1.set_title('array')
ax1.set_xlabel('x')
ax1.set_ylabel('y')
# 格子点をプロット
for x_elem in x:
    for y_elem in y:
        ax1.scatter(x_elem, y_elem, c='r')

ax2.imshow(mesh_array, vmin=np.min(array), vmax=np.max(array))
ax2.set_title('mesh_array')
ax2.set_xlabel('x')
ax2.set_ylabel('y')

plt.show()
```
```:出力結果
array:
 [[ 0  1  2  3  4  5  6  7  8  9]
 [10 11 12 13 14 15 16 17 18 19]
 [20 21 22 23 24 25 26 27 28 29]
 [30 31 32 33 34 35 36 37 38 39]
 [40 41 42 43 44 45 46 47 48 49]
 [50 51 52 53 54 55 56 57 58 59]]
mesh_array:
 [[ 0  1  3  5  9]
 [10 11 13 15 19]
 [40 41 43 45 49]
 [50 51 53 55 59]]
```
出力結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1599258/f485bd8b-2c97-a9e4-6db0-8c6172d5c160.png)

## bool型の例
bool型でも[整数型の例](#整数型の例)と同様の結果を得ることができるので紹介する。
```Python:bool型の例
import numpy as np
import matplotlib.pyplot as plt

array = np.arange(6*10).reshape(6, 10)
x = [True, True, False, True, False, True, False, False, False, True]  # 変更箇所
# np.nonzero(x) -> (array([0, 1, 3, 5, 9]),)
y = [True, True, False, False, True, True]  # 変更箇所
# np.nonzero(y) -> (array([0, 1, 4, 5]),)
mesh_array = array[np.ix_(y, x)]

print('array:\n', array)
print('mesh_array:\n', mesh_array)

"""2次元ヒートマップで表示"""
fig, (ax1, ax2) = plt.subplots(ncols=2, figsize=(10, 12))

ax1.imshow(array, vmin=np.min(array), vmax=np.max(array))
ax1.set_title('array')
ax1.set_xlabel('x')
ax1.set_ylabel('y')
# 格子点をプロット
for x_elem in np.nonzero(x)[0]:
    for y_elem in np.nonzero(y)[0]:
        ax1.scatter(x_elem, y_elem, c='r')

ax2.imshow(mesh_array, vmin=np.min(array), vmax=np.max(array))
ax2.set_title('mesh_array')
ax2.set_xlabel('x')
ax2.set_ylabel('y')

plt.show()
```
出力結果は、[整数型の例](#整数型の例)と同様である。

# まとめ
``numpy.ix_``の使い方を紹介しました。結構マイナーだと思いますが、使い所によっては便利なので是非取り入れて快適なnumpy環境を作っていきましょう。

# 参考資料
https://numpy.org/doc/stable/reference/generated/numpy.ix_.html
React-route-domのusenavigateの使い方

usehistoryは主にページ遷移をする際に使われます。
そして、React-route-domのv6からは、usehistoryからusenavigateを使用します。
自分自身v6なのに、間違ってusehistoryを使用してエラーが出てしまうといったことがあるので、使い方を説明します。

## usehistoryの場合

```JavaScript
import {useHistory} from "react-router-dom"

const history = useHistory();
history.push("/");
history.goBack();

```


## usenavigateの場合

```JavaScript

import {useNavigate} from "react-router-dom"

const navigate = useNavigate();
navigate("/");
navigate(-1);

```

基本的には、使い方は同じで、違いとしては、usenavigateだとpushを使用しないでも使えます。
１つ前に戻る時の書き方は若干異なります。
Elastic Load Balancingとは

# ELBとは
**Elastic Load Balancing**(**ELB**)とは、AWSが提供するロードバランサー。
**ロードバランサー**とは、サーバーに集中するアクセス（トラフィック）を複数のサーバーやネットワークに振り分ける仕組み。
ひとつのサーバーにかかる負荷を分散させるので**負荷分散装置**と言う。
# ELBの種類
* ALB
* NLB
* CLB
の３種類が存在する
## ALB(Application Load Balancer)
HTTPおよびHTTPSに最適なロードバランサー。
OSI参照モデルにおけるアプリケーション層（具体的な通信を提供する層）で動く
要求コマンドなどの命令内容を見て判断するので、宛先のURLのディレクトリ単位で振り分けることもできる
インスタンスとロードバランサーとの通信を暗号化できる
ただし、振り分け先として静的IPアドレスを設定し、そのIPを持つホスト（機器）へ転送はできない
対応プロトコル：HTTP,HTTPS
## NLB(Network Load Balancer)
OSI参照モデルにおけるトランスポート層（送信されたデータの制御を担う層）で動く
バケットと呼ばれる断片データしか見ないのでALBほど細かい振り分けはできない
振り分け先として静的IPアドレスを設定したり、
サーバーにアクセスしてきたクライアント側のIPアドレスをそのままサーバーに伝える設定にしたりできる
対応プロトコル：TCP,TLS

## CLB(Classic Load Balancer)
古いタイプのロードバランサー。
対応するプロトコルが多い。
しかし、これから作るシステムでは使わないべき。
対応プロトコル：TCP,SSL/TLS,HTTP,HTTPS
# ELBの料金
ALBとNLBの料金は、時間あたりの使用料金と、**LCU**（**ロードバランサーキャパシティーユニット**）料金の合計で算出される
**料金** = **使用料金** + **LCU**
## 使用料金（使用単価×時間）
使用料金はELBの種類ごとに単価が決まっていて、それに時間をかけた金額
## LCU料金（LCU使用量×LCU単価×時間）
LCU料金は使用状況の４つの項目についてLCU利用量が「何LCU」に当たるかを換算し、一番大きな項目だけを課金対象にする
※LCU料金を算出するために、まずLCUの４つの項目についてLCUの使用量を換算し比較する必要がある。
* 新しい接続（１LCU＝1秒あたり25個の新しい接続）
1秒あたりの新たに確立された接続数。（イメージ）PCやスマホ、サーバーなどが新しくアクセスしてきた数。
* アクティブ接続（１LCU＝1分あたり3000個のアクティブ接続）
1分あたりのアクティブな接続数。現在繋がっている接続の数
* 処理した量（１LCU＝1時間あたり１GB）
ロードバランサーによって処理されたHTTP(S)リクエストと応答のバイト数。Lambda関数がターゲットの場合は１LCU=1時間あたり0.4GBで換算
* ルール評価（１LCU＝1秒あたり1000個のルール評価）
ロードバランサーにより処理されたルール数とリクエストレート（1秒間に送られたリクエスト数）の積
以上の４項目が何LCUなのかを比較し、最大値の数値をLCU使用量として代入
Tableau DATA Saberに挑戦してみた

# Tableau DATA Saberとは？
- 非公式のTableau資格．
- 3か月で独自のTableau及びデータドリブンに関する様々なプログラムをクリアすることでDATA Saberを名乗ることができるようになる．

# DATA Saberを名乗るための道のり
1. すでにDATA Saberの資格を持つ師匠を見つける．
1. 認定試験にクリアする．
    - 認定試験は「コミュニティ活動」，「技術試験」の2つに分かれる．
    - 「コミュニティ活動」では「組織内」，「パブリック」の分野でTableauに関連した啓発活動を行い，ポイントを獲得する必要がある．(この記事を書いているのもまさしく，パブリックのポイント獲得のためです)
 1.  師匠からの最終試練をクリアする．

# チャレンジにかかった時間
上述の通り，まだチャレンジ中の身ですが，大体40~50時間必要です．
技術試験の問題が大問10問ほどあり，それに各2~4時間，コミュニティ活動に10~20時間必要なイメージ．

ただし，私の場合DBやSQLの考えに慣れ親しんでいたため，そういった下地がない方の場合はもっと時間が必要かもしれません．
Lennard-Jones Potentialをプロットしてみたよ

# ペアポテンシャル
化学の勉強をしているとある原子に働く力だったりエネルギーを知りたいなって時があります。ある一つの原子が感じるポテンシャルは、他の原子一個からの個々のポテンシャル$ \phi_i$を考えて、その足し合わせが原子が感じる全ポテンシャル$ \Phi$としていいよねっていうのがペアポテンシャルの考え方です。

$ \Phi = \sum_{N} \phi_i$

$ \phi_i$が$i$番目の原子から受けるポテンシャルで系中の$ N$個の原子分足し合わせています。
静止している原子に関してはポテンシャルがそのまま原子のエネルギーとしていることが多いと思いますし、エネルギーの位置微分がその原子にかかる力$ F$と考えられます。

$ F = \frac{\delta}{\delta r} \Phi$

原子のポテンシャルがわかっちゃえば、エネルギーも加わる力もわかって便利ですね。ペアポテンシャルの中でとりわけ有名なのがLennard-Jones potentialです。レナードジョーンズポテンシャルって読みます。

# Lennard-Jones potential

Lennard-Jones potentialは斥力と引力の足し合わせでポテンシャルを表現します。導出はここではしません。

$ U(r) = 4 \epsilon [(\frac{r_{ave} / \sqrt[6]{2}}{r})^{12} - (\frac{r_{ave}  / \sqrt[6]{2}}{r})^{6}]$

ここで$r$, $\epsilon$, $r_{ave}$はそれぞれ原子間距離、安定化エネルギー、最安定距離です。引力はポテンシャルが小さくなる項、つまりマイナスの第二項に相当します。この引力の起源は励起双極子-励起双極子間相互作用で、van der Waals相互作用とよく呼ばれる力です。

このvan der Waals相互作用は電気相互作用に比べて小さいです。したがって、Lennard-Jones potentialは電気相互作用が働かない電荷を帯びない原子間でよく成り立ちます。




詳しい解説はキッテルに載ってます。キッテルでも斥力の導出はしてないですが引力の解説はバッチリです。キッテルはいいぞ。
・Charles Kittel著、宇野良清 津屋昇 新関駒二郎 森田章 山下次郎 共訳「キッテル固体物理学入門」第8版、丸善出版、2015


## プロットしよう
さて、ここからが本題です。プロットしていきましょう。

```Python
import matplotlib.pyplot as plt
import numpy as np

#Lennard-Jones potential
ep = 1 # 安定化エネルギー
r_ave = 2.5e-10 # 最安定原子間距離 

rho = 2**(-1/6)*r_ave

r_length = 100000

r = np.linspace(1e-10,9e-10, r_length)

U = 4*ep*((rho/r)**12 - (rho/r)**6)
U1 = 4*ep*(rho/r)**12
U2 = -4*ep*(rho/r)**6

dy = 0*r

fig_e = plt.figure()
ax_e = fig_e.add_subplot(111)

plt.ylim(-2, 2)
plt.plot(r, U)
plt.plot(r, U1, linestyle="dashed")
plt.plot(r, U2, linestyle="dashed")
plt.plot(r, dy, color='k', linestyle="dashed")

ax_e.set_xlabel('Distance[m]', fontsize=20, color='black')
ax_e.set_ylabel('Energy[eV]', fontsize=20, color='black')
```
安定化エネルギー$\epsilon = 1$[eV]、$r_{ave} = 2.5$[10$^{-10}$m]としてます。
次に実行結果を示します

![Lennard-JonesPotential.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2804113/de447da7-7c72-d656-3ce7-799c7fb7d48b.png)

いい感じですね。
青線がLennard-Jones potentialです。緑点線がvan der Waals相互作用、橙点線が斥力です。黒点線がポテンシャル0を表しています。遠くの方から考えると、まず、ポテンシャルは無限遠で0になっています。そこから原子間距離が近づくにつれて、まず引力のvan der Waals相互作用が大きくなりポテンシャルが負の値を示します。ポテンシャルが負の値のときエネルギー的に安定です。最安定な原子間距離$r_{ave} = 2.5$[10$^{-10}$m]で安定化エネルギー$\epsilon = 1$[eV]分だけポテンシャルが減少したのち、斥力が大きくなりポテンシャルが正に発散していきます。このポテンシャルから二つの原子は近づきすぎず離れすぎずのちょうどいい距離感のところで安定になるのだとわかります。付かず離れずのちょうどいい距離感が大切ってところは原子も人間もおんなじみたいです。
ViewStubを含むレイアウトは、ViewStubをinflateしたあとにViewBindingへのbindができないので注意しよう

タイトル通りの罠にはまったので書きます

通常ViewBindingはActivityやFragmentの最初にinflateもしくはbindするだけなので問題は起こらないでしょうが、常時必要ではないモジュールにviewだけを渡して内部で再bindしている箇所があり、そこにViewStubを追加したことで問題が発生しました。

ViewStubを含むレイアウトを扱う際に、以下のようにinflate後にViewBindingへbindしようとすると

```kotlin
val binding = HogeBinding.bind(view)
...
binding.viewStub.inflate()
...
HogeBinding.bind(view)
```

NullPointerExceptionが発生してクラッシュしてしまいます。

```
Caused by: java.lang.NullPointerException: Missing required view with ID: com.example.myapplication:id/view_stub
```

ViewStubの仕組みを考えれば当然ではあります、
ViewStubの`inflate()`の実装は以下のようになっていて、`replaceSelfWithView()`で自分をViewParentから削除し、inflateしたViewに入れ替えます

```java
    public View inflate() {
        final ViewParent viewParent = getParent();

        if (viewParent != null && viewParent instanceof ViewGroup) {
            if (mLayoutResource != 0) {
                final ViewGroup parent = (ViewGroup) viewParent;
                final View view = inflateViewNoAdd(parent);
                replaceSelfWithView(view, parent);

                mInflatedViewRef = new WeakReference<>(view);
                if (mInflateListener != null) {
                    mInflateListener.onInflate(this, view);
                }

                return view;
            } else {
                throw new IllegalArgumentException("ViewStub must have a valid layoutResource");
            }
        } else {
            throw new IllegalStateException("ViewStub must have a non-null ViewGroup viewParent");
        }
    }

    private void replaceSelfWithView(View view, ViewGroup parent) {
        final int index = parent.indexOfChild(this);
        parent.removeViewInLayout(this);

        final ViewGroup.LayoutParams layoutParams = getLayoutParams();
        if (layoutParams != null) {
            parent.addView(view, index, layoutParams);
        } else {
            parent.addView(view, index);
        }
    }
```

ViewBindingはbindしたときにそのレイアウト内に存在するすべてのViewIdを捜し、フィールドに保持します。そのとき、一つでも見つからないViewがあればNullPointerExceptionを発生させます。
`inflate()`が実行された時点でこのViewStubがViewTreeから削除されてしまうため、再度bind仕様とすると、ViewStubに該当するViewが見つからず、NullPointerExceptionが発生してしまうのですね。

また、inflateされるレイアウトのRootViewにViewStubと同じIDをつけている場合、同じIDのViewに置き換わりはしますが、ViewStubのインスタンスではなくなっていますので、ClassCastExceptionが発生することになります。

これはViewStubに限ったことではなく、動的にViewを削除するようなことをしている場合、同様の問題が発生します。
ViewBindingはレイアウトのinflate以降、Viewの構造が変化した後にbindすることがないように注意しましょう。

以上です。
Laravel CRUDを実行するコントローラの役割

## CRUDとは

読み方を`クラッド`と読み、システムに必要な主要機能4つの頭文字を並べた用語です

- Create(生成）
- Read(読み取り）
- Update（更新）
- Dlete(削除）

社員管理システム、売上管理システムなどを構築する際に必要な
最低限の機能群になります。

## CRUD機能に必要なコントローラーとは

ブラウザの`フォームに入力された情報`が、コントローラーを中継して
データベースに`アップロード`を行い、`新しいページ`を開きます
逆にデータベースからコントローラを中継してブラウザに情報を渡すことを目的とします。


## CRUDの各機能を動かすスケルトン（雛形）を作る

CRUDを各々実行するには次の7つの操作（アクション）が必要になります

- 一覧表示(index)
    - データベースのレコード一覧を表示するページを表示させる
- 新規作成（create)
    - 新規レコードを追加作成するフォームがあるページを表示させる
- 保存（store)
    - フォームに入力された情報をデータベースのレコードに保存し新しいページを表示させる
- 詳細表示（show)
    - 1件のレコード詳細情報をブラウザに表示させる 
- 編集（edit)
    - 詳細表示で表示されたレコードを編集する画面を表示させる 
- 更新（update）
    - 編集画面で1件のレコードを編集した際にデータベースのレコードを更新する 
- 削除（destroy)
    - 1件のレコードを削除する
## CRUDのスケルトン（雛形）を自動生成するコマンド
本来ならば、7つのアクションをコントローラへ1つずつ記述していく必要がある所
以下のコマンドで7つのアクションを自動生成できます

``` php
    //   ターミナルやコマンドプロンプトで実行してください

php artisan make:controller *******Controller -r
     
    //   ******　＝　連動するモデル名（頭文字は大文字）を記述します
    //   -r = コントローラー作成時のオプション　Resourcefulなアクションを作成します
```


app/Http/Controllers/

``` php
class ArticlesController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        //
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        //
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        //
    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        //
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function edit($id)
    {
        //
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, $id)
    {
        //
    }

    /** 
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
        //
    }
}
```