OmniAICreator/Qiita-1.07M huggingface dataset:
Laravelで使えるリレーションを図でまとめてみたよ

# 概要

Laravelのリレーションに関するドキュメントを図でまとめてみました。
たまに何がなんだったか忘れるので忘備録。

## HasOne / BelongsTo
- ユーザー1人対して１つの電話番号が紐づいている
- 紐づくモデルが紐付き先を知っている

```mermaid
classDiagram
direction LR;

class ユーザー{
id
...
}

class 電話番号{
id
ユーザーid
携帯番号
固定電話番号
}

ユーザー --> 電話番号:HasOne
電話番号 --> ユーザー:BelongsTo
```

## HasMany / BelongsTo
- ユーザー1人に対してユーザーの投稿が複数紐づいている
- 紐づくモデルが紐付き先を知っている

```mermaid
classDiagram
direction LR;

class ユーザー{
id
...
}

class 投稿{
id
ユーザーid
投稿内容
}


ユーザー --> 投稿:HasMany
投稿 --> ユーザー:BelongsTo
```

## BelongsToMany
- ユーザーは複数の権限を所持できる


```mermaid
classDiagram
direction LR;

class ユーザー{
id
ユーザー名
}

class ユーザー所持権限 {
ユーザーid
権限id
}

class 権限{
id
ユーザー名
}

ユーザー --> ユーザー所持権限:hasMany
ユーザー所持権限 --> 権限:belongsTo
```



## HasOneThrough

- 整備士と所有者はデータベース内で直接の関係が無いが、整備士から所有者を取得したい場合に定義
:::note warn
HasOneで各モデルを繋げた場合
整備士 -[hasOne]-> 自動車 -[BelongTo]-> 所有者
:::

:::note success
HasOneThroughで各モデルを繋げた場合
整備士 -[HasOneThrough]-> 所有者
:::

```mermaid
classDiagram
direction LR;

class 整備士{
id
整備士名
}

class 自動車{
id
モデル
+ 整備士id
}

class 所有者{
id
所有者名
+ 自動車id
}

自動車 --> 整備士:BelongsTo
整備士 -->自動車 :HasOne
整備士 --> 所有者:HasOneThrough
所有者 --> 自動車:BelongsTo
自動車 --> 所有者:HasOne

```

## HasManyThrough

```mermaid
classDiagram
direction LR;

class プロジェクト{
id
プロジェクト名
}

class 環境{
id
プロジェクトid
環境名
}

class デプロイ{
id
環境id
コミットハッシュ
}
プロジェクト --> デプロイ:hasManyThrough
プロジェクト --> 環境:hasOne
環境 --> デプロイ:hasMany

```
## MorphTo / MorphOne

- 投稿の画像なのか、ユーザーの画像なのかを「紐付き先タイプ」で判別
- 「紐付き先タイプ」によって紐付き先が「投稿」か「ユーザー」を判別する
```mermaid
classDiagram
direction LR;

class 投稿{
id
投稿名
}

class ユーザー{
id
ユーザー名
}

class 画像{
id
紐付き先id
紐付きタイプ
}

画像 --> 投稿:morphTo
画像 --> ユーザー: morphTo

画像 <-- 投稿:morphOne
画像 <-- ユーザー:morphOne

```
## morphToMany / morphedByMany
- タグは投稿・または動画に複数紐づく
    - 1動画に3タグ
    - 1投稿に4タグ など
- 「紐付け先タイプ」によって動画に紐づくか投稿に紐づくかが決まる
> 図がニュアンス的にちょっと違うかもしれません
> Laravel内では$post(投稿)->tags(タグ);で紐づいているタグの取得が可能。

### DBとしての関係性
```mermaid
classDiagram
direction LR;

class 投稿{
id
投稿名
}

class 動画{
id
動画名
}

class タグ{
id
タグ名
}


class タグ紐付け {
タグid
タグ紐付け先id
紐付け先タイプ
}

タグ -- タグ紐付け:1対多
タグ紐付け --> 投稿:多対1

タグ紐付け -- 動画:多対1

```

### コード上での紐付き

```mermaid
classDiagram
direction LR;

タグモデル --> 投稿モデル:morphToMany
タグモデル <-- 投稿モデル:morphedByMany
タグモデル --> 動画モデル:morphToMany
タグモデル <-- 動画モデル:morphedByMany


```
コンポーネント原則(SDP)

# 安定依存の原則
これは安定してるものに依存しなさいっていうごく当たり前のことを言ってる原則。
安定とは変更が入りにくいものということ。
不安定は変更が入りやすいということ。

絵で思い浮かべると、地面の上に置いたテーブルの上に物を置いていくのが対応してると思います。

地面は固定していて強固に安定してるので、その上に静止させたテーブルも安定してると言えます。

そのうえに物体を置いていくと、これらの物体は下にあるテーブルに依存しているという状態。

もしもテーブルがめっちゃ左右に動くものであれば、
その上に置いた物体は静止させた状態でテーブルの上に置いても、すぐさまテーブルの揺れにつられて不安定な動きします。

なので、なるべく静止しているものの上に置きたい　⇒　変更しにくいものに依存したい。

　

## 安定度の指標
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2781175/9331523a-7efd-17bf-ef6f-6ff27f9e8d8f.png" width=60%>


たとえばこんな上図のような状態であったとき、
各A1とか　D1とかは具象クラスでも、interfaceや抽象クラスでもいい、
パッケージに属するなんかしらの要素だとする。

このときパッケージbの安定度合いは、以下の式で表せる。
パッケージb内のB1、B2、B3がどんな結合かは、ここでは一切考えない。

他のパッケージにあるものから　パッケージb内のクラス or 抽象なものに対して何本の線が引かれてるか、
これを【ファンイン】という。

対して、パッケージbから　他のパッケージ内の要素に対して何本の線が引かれてるか、
これを【ファンアウト】という。

このとき、不安程度は　不安定度 I ＝ ファンアウト / （ファンイン＋ファンアウト）　で表される。

したがって、図で言うパッケージbは　ファンアウト ＝ 2、ファンイン ＝ 3
のため、bの不安定度 ＝ 2 / 5 つまり40%　といえます。
まあ、そこそこ安定してるって感じでしょうか。

## すべてのコンポーネントに対して適用されるわけではない
何でもかんでも安定度を高めればいいってことではない。
あくまでも変更がはいりにくいものは安定させて、　頻繁に変更が入るようなものは安定させるだけ
複雑度が増してしまいそうですね。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2781175/635eb9ee-f2c0-439e-a46a-738f5e0b2aee.png" width=60%>


たとえば上記のようなこんな簡単なものを例に考えてみました。
顧客が商品を予約するっていう汎用性の高そうな業務ですね。
モデリングした結果、こんな上記のような依存関係になってたと仮定します。
まだ設計が未完成の状態のパッケージモデル図です。

仮にその業務において、以下のようなケースならどうでしょう？
①予約って概念に対して頻繁に仕様変更が入りやすいビジネス
②予約ってものよりも、顧客や商品に対して仕様変更が入りやすいビジネス
③商品て概念に対して頻繁に仕様変更が入りやすく、顧客にはそんな変更起きないビジネス

それぞれ全然違うモデルになりそうですね。それぞれ見ていきたいと思います。


### ①【予約にもっとも変更が起きやすいビジネス】
この場合は先ほどのモデル図のまんまの→矢印の向きでいいでしょう。
仮に顧客が予約に依存するような関係であった場合は、
依存関係逆転を用いて、図のように予約が顧客に依存するようにします。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2781175/38516194-a1b7-60b7-da94-fbb686b8f02c.png" width=60%>

　
### ②【予約より顧客や商品に変更が入りやすいビジネス】<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2781175/635eb9ee-f2c0-439e-a46a-738f5e0b2aee.png" width=50%>
この場合は、もともとの図のままだと
本来顧客や商品よりも安定しているはずの予約が、顧客や商品の変更によって不安定になってしまいます。
そのため以下のような状態にしなくていけません。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2781175/b2ca7561-0119-27f1-c691-e1f07fb2740f.png" width=60%>
そこで依存関係逆転を使って、１番最初のモデルからこの状態にすればいいてことですね。

　
### ③【商品に頻繁に仕様変更が入りやすく、顧客には変更起きにくいビジネス】
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2781175/7b89eade-14ba-d3c5-6a81-0f8ad7ee4926.png" width=60%>
この状態になってないといけない。

　
目指すべき形は、そのビジネスの変革の特徴を正確にとらえていないといけないってことがわかりました。
わたしはこのコンポーネント原則を通じてビジネスの変革を促すアーキテクトになりたいと強く感じました。


つまり、まとめるとその業務を構成する要素(ドメイン)は汎用的でどの業務でも同じであっても、
そのビジネスの変化の特徴は業務ごとに異なるので、
変化の特徴を正確に捉え、それが表現されてないといけないってことですね。
チームプロジェクトでAWS管理(1) - IAMユーザー

# IAMユーザーがなぜ必要か？！
### チームプロジェクトでAWSを使いたい
現在、Web Serviceの開発を勉強しているなら、誰もが一度はプロジェクトをしているはず。また、このような自分で作ったサービスを複数の人に共有してみたいと思うなら、**AWSのようなCloud Computing Serviceを使う**ことになるだろう。この時、1人でプロジェクトをしたり、チームであっても1人だけサーバー管理を担当していれば、AWSアカウント1つだけでも十分にクラウド環境を管理できるだろう。
でも、チーム内で複数の人がBack-Endを役割分担して担当していると、**１つのAWSアカウントに複数の人がアクセスしたい**ようになるだろう。だが、個人アカウントをチームメンバー全員と共有することはあまりしたくないし、AWSを使うチーム員全員がアカウントを生成すると頑張って構築したAWSリソースをアカウント間で共有できず悩みに陥るだろう。
### 私の実経験
実際に私も大学でAWSを初めて触ってみて、クラウド環境を構築しながら同じ悩みをした。毎回新しいチームメンバーとプロジェクトをする度に新しく共用AWSアカウントを作る面倒くさい作業を繰り返した。そして、決済情報で自分のクレジットカード情報が入っているので、もし**チームメンバーのなかで誰が誤った操作をしてしまい、不必要な費用請求が発生**すればどうしようかという悩みもあった。
それでも学生単位の小さなプロジェクトだったので、Free tier範囲内では問題なくプロジェクトを進めることができ、卒業するまで色々なアカウントをよく回して使用した。そのあと会社に入社すると、**各社員別にIAMユーザーアカウント**というものを発給してくれた。最初は何も考えずに使用しましたが、最近AWSの活用範囲が増えて始めた資格証の勉強を通じて「あ~こんな理由でIAMユーザーを使うんだ！！！」と感じたので、この記事を書いている。

# IAMユーザーというのは？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1050681/fefbfaa0-73a6-3ad1-46e0-6278c0336cfa.png)
IAMは**Identity and Access Management**の略。簡単に説明すると、AWSに別途のユーザー及びユーザーグループを作って、**権限内でのAWSサービス、リソースに対するアクセスを安全制御できるサービス**だ。AWSアカウントには2種類のユーザーがいますが、

* Rootユーザー
  * 私たちが一般的に使用するAWSアカウント
  * 最初のアカウント作成時に自動的に作られる
  * ログインページに「Account owner that performs tasks requiring unrestricted access.」と説明されている。
* IAMユーザー
  * RootユーザーまたはIAMユーザーのうち、管理者権限を持つ管理者が作成可能
  * 各使用ごとにAWSサービスおよびリソースへのアクセス権限を制御
  * アクセス可能な権限・レベルはユーザごとに設定も可能だが、グループ登録により制御できる。

そしてAWSでは、Rootユーザーを通じてAWSにアクセスするよりは、**ユーザー別に最小限の権限が設定されたIAMユーザーを通じてサービスを使用することを推奨**している。

# IAMユーザー作成の事前設定
### 決済情報に対するIAMユーザーと役割アクセスを有効にする
最初のIAMユーザーを生成するため、まずRootユーザーとしてログインし、ナビゲーションバーでアカウント名を選択してアカウント設定ページを開く。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1050681/04a6135e-e219-e891-6f1f-b4f35205ab23.png)
そして、アカウント設定ページを下にスクロールすると、**決済情報に対するIAMユーザーおよび役割アクセス活性化(IAM User and Role Access to Billing Information)項目**の右側にあるEditを押して**IAMアクセスを活性化**し、Updateをしてくれる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1050681/e575bb8e-bbed-5223-600f-ac5bcdf94468.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1050681/48b3c2de-4c59-4ac4-05ad-ec3728d61406.png)
コンポーネントの原則(ADP)

# コンポーネントの原則
まず先にコンポーネントの結合に関する３原則の方が言ってることは簡単なんで
そちらから先に書かせていただきます。
わたしはこの３つの原則を読んでみて、設計の楽しさのきっかけとなりました。
なぜなら依存関係逆転原則を用いて、変化が起きにくいものに依存するように依存関係を制御したりする仕組みを
この原則を交えながら学ぶことで、ビジネスの変化に強い土台を作れると感じたためです。

## 非循環依存関係の原則
![クラス図0 (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2781175/b2bbbd21-19d7-ebc2-3e7f-e97f0caae29f.png)

これは上図のようにクラスであっても、パッケージとかであっても循環してるのはやめてね
という当たり前の原則。
あとの２つの原則とも絡み合っていて、とてもいい設計指針になる原則ですね。

知らない間に循環参照になってたっていうケースはあるようですので、
もしも循環参照してたら警告でてくれるツールとかをうまく導入することで防ぐことがいいのかなと。

改善策としては、このままだと循環参照になってしまうってときは、
DIP依存関係逆転原則を適用して、interfaceをかましてあげればいい。

【具体例】
![クラス図0 (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2781175/33360bdb-9a55-506e-f94d-8b3cd55bbaad.png)

ここでは、c 、 b 、aの順に安定した(変化が起きにくい)モジュールて前提があることにします。
図でいうといまa→b→c→a となってしまってます。　
こりゃまずいですね。循環しているから、変更の影響のとくていはもはやカオス、、、。

しかも、安定していてほしいcは、不安定なaに依存してしまっています。
これでは安定していてほしいものcが、不安定なcの変更に振り回されてしまいます。

本来なら安定しているcにaが依存しているという構図になっていてほしいです。
そこでaとcの依存関係を逆転させるため、cの方にinterfaceを置いてあげることで、
図のように依存関係を逆転させ、cがもっとも安定した構図にできます。

このinterfaceを置いてあげるというのは、結果的にcの抽象度を上げることになるため、
非循環依存の原則を満たすための実現手段として、特にSAP(安定度、抽象度等価原則)を自然とやっている
て関係性のようですね。

てことで、この原則は後述の原則と絡めながら理解を深めていきたいと思います。
### →　つづく
予測フラグと確信度から傾向スコアを求める(SPSS Modeler データ加工逆引き8-14)

# 予測フラグと確信度から傾向スコアを求める(傾向スコア)

![スクリーンショット 2022-09-24 17.04.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/54b1786c-0995-7c14-2181-420949dd3c24.png)

＊傾向スコアはModeler搭載のほとんどのアルゴリズムで自動計算されますが、PythonやRのライブラリを呼び出した際に必要です。

![スクリーンショット 2022-09-24 17.17.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/c4fb6e8c-7282-5f88-453d-a9ca7a36e049.png)

## 1.想定される利用目的

・XgboostTreeのようなPython由来のモデルで傾向スコアを利用する


## 2.サンプルストリームのダウンロード

https://github.com/yoichiro0903n/blue/blob/main/propensity_score.str?raw=true

## 3.サンプルストリームの説明

![スクリーンショット 2022-09-24 17.10.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/02145994-4868-64a6-7325-f5cb828b62e6.png)

a.入力するデータは以下の通りです。XgboostTreeで解約を予測し、モデルナゲットを通過させた予測フラグと確信度のふたつのフィールドが含まれています。
![スクリーンショット 2022-09-24 17.12.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/a9b93683-9b82-2847-dc8f-cf316a3cd780.png)

b.[フィールド作成]ノードを編集します。予測フラグが0の場合には確信度を反転させます。
![スクリーンショット 2022-09-24 17.12.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/0144f6d1-a9c9-58e0-45f8-c1ce2f635376.png)

c.[テーブル]ノードを編集します。結果が分かりやすくなるように、予測フラグが0のレコードを赤字にします。
![スクリーンショット 2022-09-24 17.14.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/4b107eb2-1329-60f8-bc8e-228153c37cd8.png)

[実行]ボタンを押します。
![スクリーンショット 2022-09-24 17.15.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/60e2fe14-a3bd-d738-bdfa-483e9c7e6efe.png)

#### 注意事項

ほとんどのモデルでは作成時またはナゲットに傾向スコアの出力が準備されています。

![スクリーンショット 2022-09-24 17.17.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/eebe4388-1d7c-da06-65c9-4966f91fbf31.png)


## 4.参考情報

#### 傾向スコアを扱った記事

https://www.ibm.com/blogs/solutions/jp-ja/modeler-tips-07/

https://qiita.com/kawada2017/items/7570c0eed65a321a7dc5

#### SPSS Modeler ノードリファレンス目次

https://qiita.com/416nishimaki/private/503037195081d3323eee

#### SPSS Modeler 逆引きストリーム集（データ加工）

https://qiita.com/416nishimaki/private/4bf813e6cba84b2a1008
PetaLinuxのカーネルにパッチをあてる

# 環境

- PetaLinux 2020.2

# 方法

[PetaLinux 2020.2のRelease Notes](https://support.xilinx.com/s/article/75775?language=en_US)を確認する。

LinuxのGitリポジトリとタグが分かる。

![09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404447/f91c0465-e30a-716e-0dfa-0cdd00f31d44.png)

適当なフォルダにcloneする。

```bash
$ git clone https://github.com/Xilinx/linux-xlnx.git
$ cd linux-xlnx
$ git checkout xlnx_rebase_v5.4_2020.2
```

カーネルをカスタマイズする。

パッチファイルを作成する。

```bash
$ git diff > sample.patch
```

作成したパッチファイルを {PetaLinuxのプロジェクトフォルダ}/project-spec/meta-user/recipes-kernel/linux/linux-xlnx/ 以下にコピーする。

{PetaLinuxのプロジェクトフォルダ}/project-spec/meta-user/recipes-kernel/linux/linux-xlnx_%.bbappendファイルを作成し、内容を以下のように編集する。

```linux-xlnx_%.bbappend
FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"

SRC_URI += "file://sample.patch"

```

PetaLinuxをリビルドする。

```bash
$ petalinux-build
```

# 参考URL

- https://support.xilinx.com/s/article/75775?language=en_US
- https://www.fpgadeveloper.com/how-to-patch-petalinux/
- https://github.com/Xilinx/linux-xlnx
【CSS】2022年に追加されたCSSの機能にフィードバックしませんか？

## はじめに
2022のCSSでは、今までにない速さでアップデートが繰り返され、いろいろなプロパティが公開されてきました。

IEがサポート終了になり、今までに使えなかったプロパティが使えるようになったり、
コンテナクエリ `@container` や サブグリット `Subgrid`など、記憶に新しいものが多いと思います。

そんな中で、`State of CSS 2022`という、CSSの機能に関するアンケートが2022/10/3〜スタートしました！


そのため、この記事では、State of CSS 2022の紹介と、アンケートにご協力をお願いする記事になります。
(アンケートの運営者とは無関係です。笑)


↓ こちらから回答お願いします。

https://survey.devographics.com/ja-JP/survey/state-of-css/2022?source=leaverou


## State of CSS 2022
![image1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390720/22b8e976-6525-747e-3882-01f05b9e86d8.png)
### State of CSS 2022とは？
State of CSS は、毎年行われるCSSのトレンドに関するアンケートです。
そのアンケートが2022/10/3〜公開されました。

実は、State of CSSは、2019年からCSSの年次調査では、世界中からフィードバックを収集して、CSSの動向を把握しようと試みがされており、CSS開発者だけでなく、ブラウザーの開発者にとっても貴重な調査となっているそうです。

そのため、今年のCSSの動向を把握し、CSS開発者やブラウザーの開発者の手助けになっているようです。

そのため、CSSをつかう僕らの意見を知ってしてもらうために、
アンケートに回答して、反映してもらいましょう！

### どんなこと聞かれるの？
State of CSS 2022 では、14項目について聞かれます。
聞かれる内容は以下の通りです。

1. **レイアウトについて**
    + `subgrid`や `wrigting-modes`などのレイアウト関連の項目
2. **シェイプ・グラフィックについて**
    + `backdrop-filter`などの形や表示関連の項目
3. **色について**
    + `color()`や`color-mix()`などの色関連の項目
4. **インタラクションについて**
    + `Scroll Snap`などのインタラクション関連の項目
5. **タイポグラフィについて**
    + `line-clamp`や`variable font`などのフォント関連の項目
6. **アクセシビリティについて**
    + `color-contrast()`や`forced-colors`などのアクセシビリティ関連の項目
7. **セレクターについて**
    + `:has()`や`:where()`などのセレクター関連の項目
8. **その他の技術について**
    + `CSSの変数`や`カスケードレイヤー`などの項目
9. **CSS フレームワークについて**
    + `Bootstrap`や`Tailwind CSS`などのCSSフレームワーク関連の項目
10. **CSS in JSについて**
    + Styled ComponentsやStyled　JSXなどのCSS in JS関連の項目
11. **ツールについて**
    + ユーティリティやツールについての項目
12. **CSSの使用方法について**
    + CSS利用方法に関する項目
13. **CSSの勉強方法について**
    + CSSの勉強方法に関する項目
14. **回答者の属性について**
    + 年齢などの属性に関する項目


回答方法は、ほとんどが選択式になっているため答えやすいです。
選択項目も、`使ったことがある`・`知ってるが使ったことがない`・`知らない`などで、
自分の知識を確認するのにも使えそうです。

また、一部以下の画像のように、選択した項目の詳しい内容を任意で回答できるので、
熱いメッセージを記入することができます！
![スクリーンショット 2022-10-06 23.51.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390720/ac68b538-b67f-f6e6-8ac5-b26a45e7beac.png)


## まとめ
この記事では、State of CSS は、毎年行われるCSSのトレンドに関するアンケートが開催されたことを紹介しました。

私自身回答してみて、知らないフレームワークやCSSのプロパティーなどがあり、
勉強しないといけないことが明確になったとおもいます。

今後は、そのあたりの勉強しきれていなかった部分に関する記事を投稿できるように勉強していきたいと思います。

State of CSS 2022への回答は↓こちらからお願いします。

https://survey.devographics.com/ja-JP/survey/state-of-css/2022?source=leaverou

ちなみに回答終了後には、ナレッジスコアが表示されるので、
何％くらいかコメントいただけると嬉しいです。

ちなみに私は↓こんな感じでした。(93%高いのか🤔)
![スクリーンショット 2022-10-07 1.10.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390720/3a1fff5d-ca0e-dec9-8aec-b7cf8ce80f1d.png)


#### ref
https://lea.verou.me/2022/10/state-of-css-2022-now-open/

---

最後まで読んでくださってありがとうございます！

普段はデザインやフロントエンドを中心にQiitaに記事を投稿しているので、ぜひQiitaのフォローとX(Twitter)のフォローをお願いします。

https://twitter.com/degudegu2510
オブジェクト指向設計原則①

# クリーンアーキテクチャを読んでみて
## 序章
SOLIDはかなり時間をかけて学習してきたので、
インターフェイス分離の原則だけまだあまり体感が伴ってないので、
どこかで体感してみたいなと感じました。

コンポーネントレベルでの凝集性は、
それぞれ３つとも相反する特性があって、
現状は閉鎖性共通原則(コンポーネントカプセル化)に振り切った考え方なので、
運用していく中で、再利用性も考慮したうえで、落としどころを見つけていく。

さらにその落としどころが時々刻々変わっていく、変えないといけない状況っていうのが
大変そうではあるけども、とてもやりがいがありそうで体験してみたいという思いがあります。

一旦は最初０から作ったものは、コンポーネントカプセル化に振り切って保守性に特化した設計にして、
徐々に運用していく中で、再利用のための分割や、リリース作業削減のための分割を必要に応じて考慮してく
といった流れが、個人的にはしっくりくる流れかなと考えています。

とても読みやすい記事なので他の書籍と絡めながら読んでいきます。
ssh-add

備忘録です

# 基本

```
// 鍵一覧を表示
ssh-add -l

// 鍵を登録
ssh-add ~/.ssh/id_rsa

// 鍵を削除
ssh-add -d ~/.ssh/id_rsa
```

# 再起動時に読み込ませる
再起動するとssh-addした鍵が消える。
解決するには、 `.bashrc` に `ssh-add ~/.ssh/id_rsa` を追記する。
C言語極める特訓。4日目

とあるスクールでC言語学んでる。
C言語学ぶと基礎ができて高みに目指せるらしい。

もう4日目だけどせっかくだから学んだことを書いていこうと思う。
適当なポエム記事に近い。
今日はC言語の環境構築を行った。

それで1日が終わってしまった。。
C言語自体の環境は昼過ぎまでに終わったけどあるチェックツールを入れるのにかなり時間くった。
結局ドッカーインストールしてgithubからcheckツールもってきた。
周りの進んでる人はもうかなり先いっててつらい。

vscode使ってるけど個々のターミナルがコマンドプロンプトと勘違いして、かなりalias設定に戸惑った。
結局powershellでも設定は引数があるためできず。
関数使えば行けるらしいが俺はできなかった。
なのでメモ帳にそのコード書いて終わり。

ちなみにC言語は全くわからんです。
Scala開発環境のDockerイメージ構築時のエラー

### 開発環境
Windows10 Home 64bit
Docker Desktop For Windows : 4.12.0

### 実施内容
下記DockerfileからScala開発環境のイメージ構築を行おうとした。
```Dockerfile
FROM ubuntu:22.10

ARG JDK_VERSION="19-amzn"
ARG SBT_VERSION="1.7.2"

SHELL ["/bin/bash","-c"]
RUN apt-get update  \
    && apt-get install -y curl zip unzip
RUN curl -s "https://get.sdkman.io" | bash
RUN source "$HOME/.sdkman/bin/sdkman-init.sh" 
RUN sdk install java $JDK_VERSION
RUN sdk install sbt $SBT_VERSION


CMD ["bash"]
```

### エラー内容
イメージ構築を行うと以下のようなエラーが発生した。
```
Step 8/9 : RUN sdk install sbt $SBT_VERSION
 ---> Running in fe53f05eced6
/bin/bash: line 1: sdk: command not found
Error response from daemon: The command '/bin/bash -c sdk install sbt $SBT_VERSION' returned a non-zero code: 127
Failed to deploy '<unknown> Dockerfile: Dockerfile': Can't retrieve image ID from build stream

```

### 解決策
下記のファイルを参考にソースを変更したところエラーが解決した。

https://github.com/Lyshnia/sdkman-docker/blob/master/server/Dockerfile

```Dockerfile
FROM ubuntu:22.10

ARG JDK_VERSION="19-amzn"
ARG SBT_VERSION="1.7.2"

SHELL ["/bin/bash","-c"]
RUN apt-get update  \
    && apt-get install -y curl zip unzip
RUN curl -s "https://get.sdkman.io" | bash
RUN source "$HOME/.sdkman/bin/sdkman-init.sh" && sdk install java $JDK_VERSION
RUN source "$HOME/.sdkman/bin/sdkman-init.sh" && sdk install sbt $SBT_VERSION

CMD ["bash"]
```

### 総括
現状、なぜこの変更を行うことで解決したか理解できていないため、詳しく調べる必要がある。(2022/10月現在)
NextでCan't import the named export 'O_TRUNC' (imported as 'O_TRUNC') from default-exporting module (only default export is available)


Nextの`@semaphore-protocol/proof`のimportで下記のエラーが出る場合

```
./node_modules/fastfile/src/fastfile.js
Can't import the named export 'O_TRUNC' (imported as 'O_TRUNC') from default-exporting module (only default export is available)
```

以下のように書き直す

```
const { generateProof, packToSolidityProof } = require("@semaphore-protocol/proof");
```
LVM、PV、VG、LVについて

●LVM (Logical Volume Manager) 
物理的な記憶デバイスの領域複数まとめてひとつの大きな仮想的な領域とし、そこから仮想的なパーティション領域を切り出すことで、従来の物理的なパーティションを用いた方法よりも柔軟に記憶領域を管理することができるようにする仕組み。

LVM を構成する手順：

1. fdisk コマンドによる LVM 用パーティションの作成
2. pvcreate コマンドによる PV の作成
3. vgcreate コマンドによる VG の作成
4. lvcreate コマンドによる LV の作成
5. mkfs コマンドによるファイルシステムの作成
6. ファイルシステムのマウント

LV のデバイスファイルは /dev/VG名/LV名 。
作成した LV を実際に使うためには、このデバイスファイルを指定してファイルシステムを作成し、マウントを行い

●物理ボリューム (PV)：物理的なハードディスクやパーティション

ボリュームグループ (VG)：物理ボリュームを集めて作る、仮想的な領域

論理ボリューム (LV)：ボリュームグループの一部（または全部）を使って作る、仮想的なパーティション。従来のパーティションと同じように、この論理ボリューム上にファイルシステムを作って利用可能

●物理エクステント (PE)
LVM による領域管理の最小単位。物理ボリュームはこの物理エクステントの集合として管理され、論理ボリュームもこれを単位として作成される


■物理ボリューム (PV) 関係のコマンド
・pvcreate PVを作成
・pvremove PVを削除
・pvmove PVのないようを移動
・pvdisplay PVの情報を表示

■ボリュームグループ (VG) 関係のコマンド
・vgcreate VGを作成
・vgremove VGを削除
・vgextend VGniPVを追加
・vgreduce VGからPVを削除
・vgdisplay VGの情報を表示
・vgrename VGの名前を変更
・vgchange VGの有効化/無効化、VGのパラメータ変更

■論理ボリューム (LV) 関係のコマンド
・lvcreate LVを作成
・lvremove LVを削除
・lvextend LVを拡張
・lvreduce LV縮小
・lvdisplay LVの情報を表示
・lvrename LVの名前を変更
・lvchange LVの有効化/無効化、VGのパラメータ変更

▲論理ボリューム (LV) を縮小するコマンドは lvreduce 。
元のサイズ以下の任意のサイズに領域を縮小することができます。
また、その際にアンマウントやシステムの再起動は必要ありません。

ただし、lvreduce で LV を縮小する際、その LV 上に構築されているファイルシステムのサイズまで自動的に縮小されるわけではありません。
LV を縮小した結果、LV 上のファイルシステムのサイズより小さくなると、データが破損してしまいます。
ext2/ext3/ext4 であれば resize2fs、ReiserFS であれば resize_reiserfs、 XFS では xfs_growfs コマンドを利用して、事前に縮小後の LV サイズに合わせてファイルシステムも縮小しておく必要があります。

●lvcreate コマンド
書式：lvcreate [オプション]　ボリュームグループ名

・-L 続けてボリュームサイズを指定
・-n 続けてボリューム名を指定
・-sスナップショットを作成

※スナップショットは、ある瞬間の論理ボリュームの状態を記録しておくことができる機能で、差分を利用した仕組み。

スナップショットが作成されていると、元ボリュームに対する変更内容が監視され、必要に応じてスナップショット領域にデータが移されます。
例えば、元ボリュームのあるファイルに変更が加えられた場合は、そのファイルの変更直前コピーをスナップショット領域に保存。
こうすることで、スナップショット領域は元ボリュームのデータのうち、スナップショット作成後に変更があったものだけを保持すればよいことになり、容量を節約することができます。

ただし、スナップショットを作成したままにしておくと、その後も変更点の監視がずっと続き、また変更点がスナップショット領域に蓄積され続けてしまいます。
これはパフォーマンスに響きますので、スナップショットは不要になった際にきちんと削除しておかなければならない。




●lvm.conf（LVMボリュームの検索フィルタ）
上記のように作成されるLVMのボリュームですが、システム起動時にどの物理ブロックデバイスをLVMボリュームとして検索対象とするかを、正規表現を用いて指定することができます。ボリューム検索にはvgscanというVGを検索するコマンドが動作しますが、これに対するフィルタをlvm.confに記載することになる
著名なミラン・クラジュン教授「ビジネスと個人の成功の方法」専門カウンセリング特別オファー

ミラン・クラジュン（Milan Krajnc）博士は、ビジネスと個人の成功の向上を支援するリニューアルした心理療法士です。ミラン・クラジュンは、企業、自治体、国のさまざまな個性が引き起こす問題を解決する専門家です。経済界への多大な貢献により、ノーベル経済学賞にノミネートされました。
![prof_MilanK.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2784576/adbae29f-c59b-4a7c-5177-84efc5400656.jpeg)

ミラン・クラジュンク教授は、現代におけるビジネス脳科学の最も傑出したパイオニアの一人です。彼は、著書「ダイナミック・リーダーシップ・モデル」で表現しているように、自然の神秘を開くダイナミロジー（Dynamilogy）の研究を通じて世界経済に論理的な貢献をされ、2021年のノーベル経済学賞に指定されました。

人間の本質的な欲求や感情の向上に伴い、世界経済も変化しています。経済は利用ニーズに依存します。「ダイナミック・リーダーシップ・モデル」は、物質科学の法則と脳の研究・実行を必需品の経済的問題に結びつけ、それぞれの相互作用を決定的に構造化したものです。

クラジュン氏は、欧州の和平と改善の行政学教授であり、モナコの領土にある統一協会が定めた和の大学のアルカリファビジネスカレッジの通貨科学教授と代表であります。

彼は、「根本的な再設計を行う上で、最も厄介なのが人である」と言っています。「彼らは安定した方法で仕事をすることに慣れているため、思いがけない方法で事業に向けて動く必要があるからだ。また、固定的なデザインに陥らないよう、常に進歩を考えなければならない。再整理は、グループ全員で行うことが最も早く終わる方法であり、重要である。再整理はゆっくりと行うべきである。一瞬の遅れもなくすべてを変更することによって、騒乱に至らなくても、必ず混乱を及ぼす。

彼は、長年心理療法の分野で秘密の診療所を運営してきました。組織や個人経営の会社の緊急事態を解決する仕事を長く続けています。リーダーシップと人脈について、何百冊もの書籍と論理的な記事を執筆しています。「ダイナミック・リーダーシップ・モデル」と名付けられた作品は、積極的に11の方言に翻訳され、まだ他の多数も予定されています。

彼は、私たちの人生を鷹の理論で考えています。鷹は鳥類の中で最も寿命が長く、70歳まで生きます。しかし、そのためには、40歳を過ぎてから、相対的に多くの "負荷 "を捨てなければなりません。

その結果、ほとんど悪質な変化が起きることがありません。長くて鋭い嘴のねじれ。鷹の鉤が長く、適応的になり、使用不能になります。そのため、鷹は二度と効果的に獲物を手に入れることができません。厚い羽毛を持つ古くて重い翼は、飛行中に失速します。古く重みのある翼の固着により、飛行や追撃が次第に困難になります。このように、鷹には2つの選択肢が残されます。塵をかぶる、または150日間ずっと続く本物の変化である、耐え難い進歩のコースに乗り出すかである。

変化のプロセスは山の一番高いところで始まります。鷹が飛び、鼻面の一部が砕け散るまで石をつつきます。そして、新しい鼻面が発達することを信じます。それは古い毅然とした鉤に一緒に掴みます。新しい鉤ができた時点で、古い重たい鉤も一緒に刈り取ります。

この変化には5カ月が必要です。そしてその後、晩春に再び若々しく多才で堅実な鷹としてさらに30年を経験します。

プライベートな変化についてのすべては、アマゾンで彼の品揃えにそれを追跡することができます！この本は、いくつかの方言で、「幸せな私たち、成功の私たち！」と意味します。 

特にビジネスや家庭での問題について、想像力豊かな視点を提示します。結社は、物質的な目標や個人的な目標を達成するための手法であってはなりません。社会にとっても、自然にとっても重要なものです。私たちがどのように行動し、どのような財産をつぎ込むかによって、社団から得られるものが決まってくるということを、常に心に留めておかなければなりません。

この心理的コンプレックスが大きくなった時点で、彼らのマインドフルネスは止まりました。そのため、彼らは道に迷ってしまいました。様々な専門家の助けにもかかわらず、彼らはその間、魅惑的なサークルをさまよっています。彼らの人生は、錨のロープの長さにその方法を限定して、風と海の流れの寛大さに与えられている固定されたボートに例えることができます。その正当な理由は接続することです。人生はともかく、流れるものであります。そのことを念頭に置いて、私たちは、壁に囲まれた領域に自分自身を置くことを妨げるために、アンカーの一つ一つを上げる必要があります。

ミラン・クラジュン博士は、企業、自治体、国の様々な個性によって引き起こされる問題を解決する個人とビジネスの成功の専門家です。プレミアム個人コンサルティング、企業向け上級コンサルティング、ファミリービジネス向け上級コンサルティング、公共機関向け上級コンサルティング、上級チームビルディングプログラム、意識覚醒のための上級プログラムなどのサービスを提供しています。

読者の皆様には、パーソナル・ブレイクスルーの1時間コース（150ユーロのバウチャー）のキャンペーンを実施中です。今なら、自分自身や大切な人に、最高のプレゼントができます。1枚のクーポンを購入すると、有名な専門家であるミラン・クラジュンによる1時間の専門的なカウンセリングと経験豊富なマネージメントを受けることができます。

■サービス概要
サービス名：パーソナル・ブレイクスルー : オンラインカウンセリング
場所　　　： オンラインセッション
料金　　　： 150ユーロのバウチャー／1時間
申込方法　： メール連絡先ddr@milankrajnc.mc
URL　　　： https://www.milankrajnc.com/


【本プレスリリースに関するお問い合わせ先】
ミラン・クラジュン教授
TEL：+377 678 63 69 66
MAIL：メール連絡先ddr@milankrajnc.mc
URL：https://linktr.ee/DonMilan
オフィスの住所：Le Forum, 28 Boulevard Princesse Charlotte, 98000 Monaco
FirestoreのLocationとDocument取得にかかる時間

## 測定結果

| FirestoreのLocation | アクセス元 | 時間(ms) |
| - | - | - |
| asia-northeast1 | asia-northeast1のCloud Run | 10 |
| asia-northeast1 | 東京にあるノートPC | 15 |
| us-central | us-central1のCloud Run | 21 |
| us-central | 東京にあるノートPC | 209 |

- 測定に使ったDocument
    - パスは"chats/xxx/messages/yyy"
    - フィールドは"body"だけで、値は"message1"
- 測定方法
    - httpサーバから200回 Document Read
    - 後半100回の時間の平均値を求めた。最初の方のDocument取得は、距離とは別の要因で遅くなる傾向があるので

当たり前だが、地理が離れた東京 - アメリカの通信時間は大分長い。

## 背景

仕事で携わっているプロダクトが、AWSの東京リージョンで動いているサーバから、us-centralのFirestoreにアクセスする構成となっている。そのせいか、FirestoreへのアクセスがAWS東京リージョンのRDBへのアクセスより遥かに遅くてつらい。

FirestoreのLocationを東京にしたら改善するのかを確認したかった。
独習プログラミングの備忘録　4 前編　【制御構文のバリエーション】

～学んだこと～
・if分は3種類存在する
if-else文、ifのみの構文、if- if else -else文

・Switch文を用いることでスッキリした条件分岐を書くことができる

・Switch文には使用条件がある
　・左辺と右辺が一致するかを比較する式であること　(「==」のみ)
　・比較する値が整数であること　(小数、文字列は不可)

・enum文を用いることで、複数のint型の定数をまとめることができる

～感じたこと～
誰もが見やすいと感じるプログラムを作成するためには冗長なコードをなくすことだ。
それに基づくと、今回学んだSwitch・enum文は大きな役割を担っていそうである。
Windowsのための環境構築 Docker Desktop WSL2 バックエンド

Windows で開発環境作るとき Linux 使えたら便利！
Windows Subsystem for Linux (WSL) 2を使ってみよう！

# 公式手順読んだ方がいい

Docker も Microsoft も公式で WSL2 開発手順を公開しているので、これさえ見ておけばいい。
Ubuntuにする？とか迷わないように決め打ちで書くが、
カスタマイズしたければ、公式を全部読んだほうがいい。
すぐ古くなるし、詳細書いてあるし、やっぱり公式見たほうがいい。

それでも処理を飛ばしちゃったりして失敗する人が多いので、現時点での手順をまとめる。

# 1. WSL2 インストール

公式: https://learn.microsoft.com/ja-jp/windows/wsl/install

## 1-1. 前提条件
Windows 10 バージョン 2004 以降 (ビルド 19041 以降) または Windows 11

## 1-2. WSL コマンドのインストール
管理者の PowerShell または Windows コマンド プロンプトで実行し、再起動
`wsl --install`

## 1-3. ユーザー情報を設定
Windows スタート メニューから Ubuntu を起動
ユーザー名とパスワードを設定

## 1-4. 確認
`wsl -l -v`
```
  NAME                   STATE           VERSION
* Ubuntu                 Running         2
```

# 2. Docker Desktop インストール

公式: https://docs.docker.jp/desktop/windows/wsl.html

## 2-1. ダウンロード
[Docker Desktop for Windows](https://desktop.docker.com/win/main/amd64/Docker%20Desktop%20Installer.exe) 

## 2-2. インストール
WSL2 設定ができていれば、インストール中に WSL2 を有効化するかどうかの画面が出る
`Use WSL 2 insted of Hyper-V(recommended)`
**絶対チェック付けて！**

## 2-3. 設定
Windows スタート メニューから Docker Desktop を起動
Docker メニューに Settings(歯車アイコン) がある(右上)

▼ Docker で WSL2 を使う
Settings > General
`Use the WSL2 based engine` にチェックがついているか確認

▼ WSL2 で Docker の有効化
Settings > Resources > WSL Integration
`Enable integration with my default WSL distro` にチェックがついているか確認
**Ubuntuを有効化** (トグルON) ※忘れないで！

「Apply & Restart」ボタンで変更反映

# 3. ローカル開発環境

開発方法は自由ではあるが、VSCodeがおすすめ
VSCode で Ubuntu に置いたプロジェクトを開いて開発できる

## プロジェクトを取得
Ubuntu に Git インストール
`$ sudo apt-get install git`

開発リポジトリをクローンする
**※絶対にUbuntu内に作成すること！Windowsファイルシステム(/mnt/c/)だと激重になる！**

## VSCode に Remote - WSL 拡張機能をインストール
https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-wsl

## VSCodeでプロジェクトを開く
クローンしたプロジェクトのディレクトリで　`code .` を実行すると VSCode が開く
VSCode 左下 WSL2:Ubuntu となっていれば WSL2 で開いていることが確認できる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536619/3589df4e-314a-6dca-033c-f571f1327692.png)

## dockerグループにユーザを追加

WSL2ユーザでdockerコマンドを実行する場合に追加しておく

docker実行用グループ設定を確認
`$ cat /etc/group | grep docker`

ユーザがなければ追加
`$ sudo gpasswd -a ユーザー名 docker`

```
docker:x:1001:ユーザ名
```


さぁ、開発を始めよう！
知っていると役立つGoogle検索のテクニック

# 完全一致検索

検索ワードを`"`（ダブルクォーテーション）で囲む

![スクリーンショット 2022-10-07 0.13.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2689074/b67618b5-47b3-7d20-09b5-238aca5d39b7.png)

:::note
検索結果を絞り込むことが出来る
:::

# ワイルドカード
すべてのパターンにマッチする文字列として`*`（アスタリスク）を使用

![スクリーンショット 2022-10-07 0.25.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2689074/fb2a99ef-abc4-a60b-9d6f-4938b801bde2.png)

:::note
エラーの検索などで独自のファイル名やメソッド名、バージョンなどに縛られずに探したい時
:::


# マイナス検索

（例）検索結果から「ネタバレ」を除く
![スクリーンショット 2022-10-07 0.04.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2689074/03f5e1f0-cf36-f838-5feb-cd4b503bb15b.png)

:::note
`-検索ワード`で、指定したキーワードを含むページを検索結果から除外することが出来る
:::


# after:日付

- 普通に検索した場合
![スクリーンショット 2022-10-06 23.10.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2689074/d55d8f5c-14fa-f24b-c738-677c6d065a4d.png)

- `after:年`を加えて検索をした場合
![スクリーンショット 2022-10-06 23.13.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2689074/e25fb342-4f5a-a204-59ac-bf39e1ba1750.png)

:::note
指定した日付よりも新しい検索結果を表示することが出来る
:::

- `after:2022-10-01`等と、もっと具体的な日付で検索することも可能。
- 逆に、よい古い情報を検索したい場合には「**`before:`**」を用いる。


---

他にも様々な検索方法がありますが、比較的使いやすいものをピックアップしました。
特にエンジニアはググり力や新しい情報のキャッチアップが大切なので、こういった検索の方法も覚えておくと開発に役立ちます。
Pythonでbluetooth端末を検出する方法

めっちゃ前に作ったやつ非公開のやつ

```
$ pip install bleak
```

```blue.py
"""
https://qiita.com/kenichih/items/8baa27b3aecc94dd8193

https://atatat.hatenablog.com/entry/2020/07/09/003000

pip install bleak
"""

import asyncio
from bleak import discover

async def run():
    print("検出中")
    devices = await discover()
    for d in devices:
        if d.name != "Unknown" and d.rssi > -90:    #約1〜1.5mにあるとき
            print("強さ：", d.rssi, "     端末：",  d.name)

def main():
  tim = 1
  while True:
    loop = asyncio.get_event_loop()
    loop.run_until_complete(run())
    print()
    print("{}秒後再開します。".format(tim))
    time.sleep(tim)

if __name__ == "__main__":
  main()
```
CloudformationのEC2のIamInstanceProfileとは

## 勉強前イメージ

なんだっけ？聞いたことあるけどちゃんと見たことないかも
IAMに関連する？

## 調査

### EC2のIamInstanceProfileとは

EC2インスタンスとIAMロールを結びつけるための箱のようなものです。
EC2にはIAMロールを紐付けられるようになっていますが、処理的にはIamInstanceProfileを介してロールを紐づけています。

CFn書く際には以下のように書いています。

```
Type: AWS::EC2::Instance
Properties: 
  ....
  IamInstanceProfile: String
  ....
```

[AWSの公式](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-iaminstanceprofile) には以下のように書かれています。

```
IAM インスタンス プロファイルの名前。
新しい IAM インスタンス プロファイルを作成するには、 AWS::IAM::InstanceProfileリソースを使用します。

必須: いいえ
タイプ: 文字列
更新が必要:中断なし
```

GUIからEC2インスタンスを作成する際には高度な詳細から「IAM インスタンスプロフィール」で設定することが出来ます。
要するに、IAMインスタンスプロフィールの設定は意味としてはIAMロールの設定と同様の意味になります。

![1インスタンスを起動 _ EC2 Management Console - Google Chrome.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/7c1aad51-5b3b-205f-d1a4-28915041efc0.png)

## 勉強後イメージ

実際にはIAMロールをEC2に紐づけは出来ないのか・・・・
Cloudformationで始めて知ったけど、EC2のUI変わってからちゃんと名前出てるね。

## 参考

- [EC2のインスタンスプロファイルとIAMロールの実務上の違い](https://go-surftrip.hatenablog.jp/entry/2018/03/16/142241)
- [インスタンスプロファイルの使用](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_roles_use_switch-role-ec2_instance-profiles.html)
- [AWS::EC2::Instance](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-iaminstanceprofile)
Dockerを使ってPHPを実行する方法

## 目次
* 概要
* そもそもDockerってなに？
* Dockerに関する用語
* Dockerを使ってPHPを実行する
* 最後に

<a id="sec1"></a>

## 概要
プログラミングに触れてからまだ1年も経過していないですが、
先日開催されたPHPConferenceJapan2022にて人生初登壇・初LT(スポンサー枠)をさせていただきました。
子鹿みたいに足が震えていましたが、貴重な経験をさせてもらいました🦌
また別記事でスライド投稿できればと思います。
　
さて今回はスキルアップのため不定期で30分でインプットしたことを投稿の
第二弾として、Dockerを使ってPHPを実行する方法についてやっていこうと思います!
(Dockerってなに？って状態から始めたのでインプット30分じゃ終わらなかったです)
ちなみに、Macでやります。(M1チップ)

第一弾は[PhpStormの便利機能](https://qiita.com/kitamurakunihiko/items/25a8bd78b5eee9ba4c75)について投稿したのでよければ確認してみてください。
　
<a id="sec2"></a>
## そもそもDockerってなに？
噛み砕くと、
**パソコンの中に独立したパソコン(コンテナ)を作り環境を構築し、いつでもその環境を立ち上げて使える便利なもの**
ということみたいです。
コンテナ自体をアプリケーションと同じ単位で管理するため、
面倒な処理が必要なくパソコン側からも人間側からも便利なツールのようです。

他にも、同じチームメンバーに「環境(Dockerイメージ)」を共有する機能とか
GitHubみたいに環境(Dockerイメージ)を共有しておける場所(Docker Hub)や
Composerみたいに複数のコンテナを一度に起動できるもの(Docker Composer)とか色々あるみたいです。

　
<a id="sec3"></a>
## Dockerに関する用語
Dockerを調べていく上で、最低限理解しておいた方がいい用語を先にまとめておきます。

### コンテナ🗃
Docker上で動作する仮想環境のこと。
簡単にいうと、
パソコンの中に仮想パソコン(コンテナ)を作って、同時に複数の仮想パソコン(コンテナ)の稼働をさせることができるものがDocker。

### Dockerイメージ🗂
コンテナの情報が格納されているファイルのこと。
コンテナのもととなる情報で、コンテナの作成にはDockerイメージが必要になる。

### Dockerfile📂
Dockerイメージを作成するためのファイルのこと。
Dockerのもととなる情報で、Dockerイメージの作成にはDockerfileが必要になる。

### DockerHub
GitHubのDockerバージョンみたいなもので、Dockerイメージが公開されている場所です。

### DockerCompose
PHPで使用するパッケージバージョン管理ツール「Composer」のDockerバージョンで、
DockerHubから複数のDockerイメージが取得できる。

　
<a id="sec4"></a>
## Dockerを使ってPHPを実行する
ここからタイトルの内容に入っていきます。

まず手順としては、
#### 1. Dockerをインストール
#### 2. 最低限必要なディレクトリ・ファイルの作成
#### 3. コンテナの起動
の順にやっていきます。

### 1. Dockerをインストール
#### インストール方法
[公式サイト](https://docs.docker.com/desktop/install/mac-install/)やHomebrewでもインストールできるみたいです。

今回は公式サイトからインストールします。
インストール後、起動すると画面上部にクジラマークが表示されると完了です。(ターミナルで```$ docker -v```でバージョン確認でもOK)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680888/8efee92d-a1c3-c82a-ad20-82fa3e0535c7.png)

### 2. 最低限必要なディレクトリ・ファイルの作成
##### 階層は下記の通りです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680888/57ca8d07-f4e0-8b12-86ab-34735bf9e019.png)

各ファイルの記述内容は下記の通りです。    
```
//Dockerfileの記述内容
FROM php:8.0-apache
```
```
//index.phpの記述内容
<?php
phpinfo();
```
```
//docker-compose.ymlの記述内容
version: '3'
services:
  php_service:
    container_name: php_container
    build:
      context: './php/'
    volumes:
      - './php:/var/www/html'
    ports:
      - '80:80'

```


### 3. コンテナの起動
あとは起動コマンドを実行するのみです。
```$ docker-compose up -d```
コマンド実行後にログが表示されますが、最後に```done```と表示されれば成功です。

ブラウザでhttp://localhost/にアクセスしてみると、
index.phpの中身のphpinfo()：PHPの設定が表示されました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680888/e8f2787d-35fd-a2b5-9951-d7f35e6ccf4e.png)

　
<a id="sec5"></a>
## 最後に
職場でDockerを使用していないため今までほとんど何も触ったことがなかったですが、
早くて簡単に環境構築できる噂を体験できて楽しかったです！

今回は最短でインプットし記事にまとめたため、Dockerの深いところの理解やymlファイルの書き方など
しっかり理解できていないところが多々あったので、違う機会に学習して投稿していこうと思います。
GitHubのSSH接続方法を公式で推奨されているものにした

## 経緯
最近、新しくLinux環境を作った時です。
SSHにはあまり詳しくないのでGitHubにSSHするときは、いつも`github ssh 接続方法`なんかでぐぐって、トップに出てきたものを参考にしていました。
今回もそのように検索し、トップのものをクリックしようと思ったのですが、ふと見ると記事の更新日が2015年でした。
これはまずいと思って、いろいろ調べると、GitHubの公式サイトでSSHでの接続方法が紹介されていました。

## 変更点
これまで鍵を生成するとき、このコマンドを実行していました。
```
$ssh-keygen -t rsa
```
それに対して、公式サイトではこのようなコマンドが紹介されていました。
```
$ ssh-keygen -t ed25519 -C "your_email@example.com"
```
RSA暗号というのは基本情報技術者試験でも習ったので違和感なく使っていたのですが、公式ではED25519というものに変更されていたんですね。
今回気づくことができてよかったです。
公式のSSH接続手順はこちらです。

https://docs.github.com/ja/authentication/connecting-to-github-with-ssh

## まとめ
公式サイトを見ず痛い目みたのは初めてじゃないのに学習できてないです。とりあえず公式サイトを確認しよう。
WSL2とDockerで遊んでたらVSCodeでファイルを書き込みできなくなった -Error: EPERM: operation not permitted-

# 身に覚えがある行動
docker-compose.yamlを書いた
```docker-compose.yaml
version: "3.9"
services:
  web:
    build: ./web #Dockerfileのあるパスを指定する
    volumes:
      - ./html:/var/www/html #パスをマウント <HostPath>:<Container Path>
    ports:
      - 80:80 #ポートを公開 <Host IP>:<Host Port>:<Container Port>
    depends_on:
      - mysql

  mysql:
    image: mysql:8
    volumes:
      - ./mysql:/var/lib/mysql
      - ./mysql/config/my.cnf:/etc/mysql/conf.d/my.cnf
    environment:
      - MYSQL_ROOT_PASSWORD=root #適切に変更
      - MYSQL_DATABASE=test_db
      - MYSQL_USER=test_user
      - MYSQL_PASSWORD=test_password #適切に変更
    ports:
      - 3306:3306

```
コンテナを立ち上げた(WSL2)
```
$ docker-compose up
```
コンテナの中に入った(WSL2)
```
$ sudo docker exec -i -t <webのコンテナID> bash
```
コンテナの中でなんか操作した(webのコンテナの中)
```
# ls /var/www/html
```
何したか覚えていないけど変なことした気がしない。

# ハマった
- VSCodeでファイルを新規作成しようとしたらできない
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2882988/0f5f3ba6-d39b-83cf-9679-16136e19704c.png)
Error: EPERM: operation not permitted

# 権限を確認する
```
$ ls -l
total 20
-rw-r--r-- 1 user user   25 Oct  6 21:55 README.md
-rw-r--r-- 1 user user  661 Oct  6 23:09 docker-compose.yaml
drwxr-xr-x 2 root root 4096 Oct  6 23:09 html
drwxr-xr-x 3  999 user 4096 Oct  6 23:09 mysql
drwxr-xr-x 4 user user 4096 Oct  6 23:06 web
```
/html の所有者と所有グループがrootになっている。Hmmmm...

# とりあえず権限を変更する
```
$ sudo chown user -R html
$ sudo chown :user -R html
```
- 直った

# 原因
- コンテナに入ったときに、root権限で入ってしまったのが問題な気がする。

# 解決策
https://zukucode.com/2019/06/docker-user.html

なんかよくわかんないけどDockerfileに下記を追加する
```Dockerfile
ARG UID=1000
RUN useradd -m -u ${UID} docker

USER ${UID}
```
```
$ sudo docker exec -it <コンテナ名> bash
docker@1f228fef9438:/var/www/html$
```
今度は大丈夫そう。

# 追記
- mysqlの方も似たような問題が起きた
- コンテナ立ち上げた時点で問題が起きている???
- ファイルやディレクトリがWindows側(/mnt/c 配下)だともっとややこしかったかも
    - [WSLで、bundle install 時のErrno::EPERM: Operation not permittedを解決したのでメモ](https://kei-kmj.hatenablog.com/entry/2022/01/31/152351)

# あとで読む
https://qiita.com/yohm/items/047b2e68d008ebb0f001

# なんもわかんね
わかんね

# 更に追記
https://tech.fusic.co.jp/posts/2021-08-12-php8-lamp-on-docker/
>WSLのdockerを利用しているのもあり、各DockerのユーザとWSLユーザの権限をそろえておきたいので、.envでユーザIDとグループIDを渡しておきます。

これか？
いい感じのmixin作りたいけどすごい冗長的になったのでもっとカッコいいのを書き方を考え中

基本的なspacingはmarginのbottomとrightで管理したいので下記のようなmixinを作りました。

## marginのbottomとrightだけ許容する@mixinを作成
```scss
$margins: (
  small: 8px,
  medium: 12px,
  large: 50px,
);

@mixin margin($size: medium, $property: bottom) {
  margin-#{$property}: map-get($margins, $size);
}

.section {
  @include margin(large, bottom);
  @include margin(small, right);
}

// コンパイル後
.section {
  margin-bottom: 50px;
  margin-right: 8px;
}
```

### @mixinの仕様
```scss
@mixin margin($size: medium, $property: bottom)
```
`$size`と`$property`にはデフォルトの値を設定しておきます。

### Interpolation（インターポレーション）で文字列として扱う
:::note info
Interpolation（インターポレーション）`#{$property}`
利用することで動的にプロパティを操作できるようにします。

```
$property = bottom;
コンパイル前：margin-#{$property}
コンパイル後：margin-bottom
```
:::

### @errorで指定以外を弾く設定を追加
追加で`margin-bottom`と`margin-right`以外は許容したくないので、
@errorを追加してbottomとright以外を第二引数に入れるとエラーを出すようにする。
これでおかしな使われ方はできない。

```scss
@mixin margin($sizes: (), $property) {
  @if $property {
  }
  @else {
  }
  @if ($property != bottom and $property != right) {
    @error "$propertyはbottomかrightのみ";
  }
  @if (length($sizes) == 1) {
    margin-bottom: marginSize($sizes);
  } @else {
    @for $i from 1 through 4 {
      $property: join($property, $sizes);
    }
    @debug $sizes;
    //margin: marginSize(nth($sizes, 1)) marginSize(nth($sizes, 2));
  }
}
```

### 条件分の書き方は注意
:::note warn
条件式で`&&`や`||`は使えないので、`and`や`or`を利用する
:::

## 作った@mixinの課題
いい感じにできたと思いきやこれだと問題が発生します。
コンテンツ間のspacingは`@include margin($size, $property);`記述できる。
ただ、`margin: 0 auto;`や`margin: 10px 8px 12px`とか指定したいてなったら記述バラバラでそのうちカオスになるのではないか？

## 具体例
```scss
.section {
  @include margin(large, bottom);
  @include margin(small, right);
}

.section2 {
  margin: 0 auto;
}

.section3 {
  margin: 10px 8px 12px;
}
```

@mixinが対応できていない範囲は、これまで通り書かないといけません。
同じmarginを指定するのに違う書き方が存在すると後に混乱を招くかもしれない…。
意図的なのか偶発的なのかは判断できないかもしれない…

### @mixinを汎用的なものになるように拡張を試みてみる
@mixinを拡張することにしたがめっちゃ冗長的に…

```scss
@mixin margin($sizes: (), $property: bottom) {
  @if ($property != bottom and $property != right) {
    @error "$propertyはbottomかrightのみ";
  }
  margin-#{$property}: map-get($margins, $size);
}
```
### 第一引数を配列にする。
`$property`のデフォルト値をセットしている場合は諸々の判定に第一引数を使います。

```scss
@mixin margin($sizes: (), $property: bottom) {
  @if (length($sizes) == 1) {
    margin-#{$property}: map-get($margins, $sizes);
  }
  @else if (length($sizes) == 2) {
    margin: marginSize(nth($sizes, 1)) marginSize(nth($sizes, 2));
  }
  @else if (length($sizes) == 3) {
    margin: marginSize(nth($sizes, 1)) marginSize(nth($sizes, 2) marginSize(nth($sizes, 3));
  }
  @else if (length($sizes) == 4) {
    margin: marginSize(nth($sizes, 1)) marginSize(nth($sizes, 2) marginSize(nth($sizes, 3) marginSize(nth($sizes, 4));
  }
}
```
### nth()を使って配列から取り出す
:::note info
リストの指定した位置の要素を取得する nth(list, $n)
:::

もっといい書き方があるだと思ってますが…
いい記述方法を考えついたら更新します。
備忘録 GoogleTest&CMake&CTest

参考 : https://google.github.io/googletest/quickstart-cmake.html

- フォルダ構成
```
project
  +-- src : こっちに本体
  +-- test
       CMakeLists.txt
       +-- sub1
           CMakeLists.txt
           test_X.cpp
       +-- sub2
           CMakeLists.txt
           test_Y.cpp
```

CMakeLists.txt
```test/CMakeLists.txt
cmake_minimum_required(VERSION 2.8)

enable_testing()
project(test_project)

# GoogleTest requires at least C++14
set(CMAKE_CXX_STANDARD 14)

include(FetchContent)
FetchContent_Declare(
  googletest
  GIT_REPOSITORY https://github.com/google/googletest.git
  GIT_TAG release-1.12.1
)
# For Windows: Prevent overriding the parent project's compiler/linker settings
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(googletest)

add_subdirectory(sub1)
add_subdirectory(sub2)
```

```test/sub1/CMakeLists.txt
enable_testing()

add_executable(
  test_sub1
  test_X.cpp
)
target_link_libraries(
  test_sub1
  GTest::gtest_main
)

include(GoogleTest)
gtest_discover_tests(test_sub1)
```

```test/sub2/CMakeLists.txt
enable_testing()

add_executable(
  test_sub2
  test_Y.cpp
)
target_link_libraries(
  test_sub2
  GTest::gtest_main
)

include(GoogleTest)
gtest_discover_tests(test_sub2)
```

- テストコード

```test/sub1/test_X.cpp
#include <gtest/gtest.h>

// Demonstrate some basic assertions.
TEST(HelloTest1, BasicAssertions) {
  // Expect two strings not to be equal.
  EXPECT_STRNE("hello", "world");
  // Expect equality.
  EXPECT_EQ(7 * 6, 42);
}
```

```test/sub2/test_Y.cpp
#include <gtest/gtest.h>

// Demonstrate some basic assertions.
TEST(HelloTest2, BasicAssertions) {
  // Expect two strings not to be equal.
  EXPECT_STRNE("hello", "world");
  // Expect equality.
  EXPECT_EQ(7 * 6, 42);
}
```

- ビルド&テスト実行

```
$ cmake -S . -B build
$ cmake --build build
$ cd build && ctest
```
Pythonの冪乗の速度について

# 1. 概要
MD（分子動力学）の記事を書いているときにふと気になったので調べました。
以下の5通りで戦います。
- `a * a * a * ・・・`
- `a_2 = a * a, a_4 = a_2 * a_2 ・・・`
- `a ** b`
- `pow(a, b)`
- `np.power(a, b)`

# 2. 条件
- 1回のループ内で定数aを10乗させる処理を行います。
- ループ回数は100万回です。計測には`time`モジュールを使います。
- 各条件の処理は以下の通りです。
```python
for _ in range(num_loop):
    x = a * a * a * a * a * a * a * a * a * a

for _ in range(num_loop):
    x_2 = a * a
    x_4 = x_2 * x_2
    x_10 = x_4 * x_4 * x_2

for _ in range(num_loop):
    x = a ** 10

for _ in range(num_loop):
    x = pow(a, 10)

for _ in range(num_loop):
    x = np.power(a, 10)
```

# 3. 結果
## 3-1. `a = 1`
```
a * a * a * ・・・ : 0.1461648941040039
a_2 = a * a ・・・ : 0.08412599563598633 優勝!
a ** b            : 0.24338006973266602
pow(a, b)         : 0.26867198944091797
np.power(a, b)    : 0.9174587726593018
```

## 3-2. `a = 1e10`
```
a * a * a * ・・・ : 0.14845013618469238
a_2 = a * a ・・・ : 0.0875389575958252
a ** b            : 0.07700586318969727 優勝!
pow(a, b)         : 0.10171699523925781
np.power(a, b)    : 1.22843599319458
```

## 3-3. `a = 1e-10`
```
a * a * a * ・・・ : 0.14542508125305176
a_2 = a * a ・・・ : 0.08142709732055664
a ** b            : 0.06892800331115723 優勝!
pow(a, b)         : 0.10165691375732422
np.power(a, b)    : 1.2617030143737793
```

# 4. 考察
pythonの内部処理がどうなっているかさっぱりなので検証方法もざっくりです。
有識者の方は是非コメントいただけると嬉しいです:bow_tone1:
私は脳死で`**`を使おうと思います。
Igor_画像の読み込み

撮影したtiff画像をIgorに読み込むときにただ放り込むと16 bitで読み込まれてしまって後で解析をかけるときにいちいちdouble floatに直すのが面倒なので読み込みの時点でdouble floatにするためのProcedureです。名前とスケールを変えてフォルダに放り込む際に同じサイズのファイルをdouble floatで作成したうえで値だけコピーしてしまっています。

今回の実験では変数を変えながら測定して'g3900_100s_40_4'のような名前で保存した画像を後でfor loopで一括で読み込むことを想定しているので(この例ではCCDカメラにかける電圧を3900、露光時間を100 sと固定して遅延時間を40刻みで変えながら各5回測定したのでこのようなファイル名になっています)適宜ファイルの名前(FilePath)とファイルの保存場所(FolderPath)を変えて使用してください。
```
Function load_image(delay,count)
Variable delay,count
Variable gain,t
	gain = 3900
	t = 100	//sec
Variable length_x,length_y
    length_x = 150e-6
    length_y = 150e-6
String FilePath,FolderPath,FullPath
	FilePath   = "g"+num2str(gain)+"_"+num2str(t)+"s_"+num2str(delay)+"_"+num2str(count)
	Folderpath = "D:research:Experiment:20221001:"
	Fullpath   = FolderPath+FilePath+".tif"
    	Imageload/T=tiff/Q/O/N=tmpfile Fullpath
    	Wave refWave = tmpfile
String LoadName = "sub_d"+num2str(delay)+"_"+num2str(count)+"_"
Variable Num_x,Num_y
	Num_x = dimsize(refWave,0)
	Num_y = dimsize(refWave,1)
Variable step_x,step_y
    step_x = length_x/Num_x
    step_y = length_y/Num_y

String Folder = "OriginalImage"
	Newdatafolder/o/s $(Folder)
		Make/o/d/n = (Num_x,Num_y) $(LoadName)
		Wave NewWave = $(Loadname)
            setscale/p x, -(Num_x*step_x/2),step_x,NewWave
            setscale/p y, -(Num_y*step_y/2),step_y,NewWave
		NewWave = refWave
cd root:
killwaves refWave	
end
```

```
Function Auto()
Variable delay,count
for(delay = 40; delay <= 880; delay += 40)
	for(count = 1; count <= 5; count += 1)
		load_image(delay,count)	
	endfor
endfor
end
```
Castコマンドラインツールの紹介 ~ Castはいいぞ！

## Castとは
Castは、**Foundryというスマートコントラクト開発ツールに付属する、コマンドラインツールです。**
Foundryをインストールするときに一緒についてきます。Foundryについては、この[日本語の記事](https://qiita.com/oishun/items/808994e0aea83cf08d7b)が参考になるでしょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/902476/c68a4752-15bb-4a53-f025-f84735b387db.png)

## どういうことができるのか
**RPCコールの実行や変換をコマンドラインから行うことができます。**
**ターミナルから移動せずに、そのままコマンドを打つことで完結するので、時間の短縮を行うことができます。**

正直、使用できるコマンドについてはこちらの[reference](https://book.getfoundry.sh/reference/cast/)を見れば分かります。
この記事ではcastが役に立つ状況や便利さを語りたいと思います。


### 例1: アドレスをチェックサムしたい
Solidityを書いているとき、定数のアドレスをハードコードしたい時があるでしょう。Solidityではアドレスはチェックサムされていないとコンパイルできません！！ また、web3.pyはチェックサムされていないアドレスを引数に与えるとエラーが出ます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/902476/fb6f6aad-e13c-f813-42cc-718118cadc14.png)
![Screen Shot 2022-10-06 at 19.35.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/902476/242e93cd-9541-3c61-931a-4dcfe5c5c63b.png)

castなら秒でチェックサムできます！！タターンッ(エンターキーを弾く)
```
> cast --to-checksum-address 0x6b175474e89094c44da98b954eedeac495271d0f
0x6B175474E89094C44Da98b954EedeAC495271d0F
```

### 例2：カッコいいアドレスを生成したい
先頭に`0`が続くカッコイイイvanityアドレスが欲しい。
castならコマンド一発です。
```
> cast wallet vanity --starts-with=0000 
Starting to generate vanity address...
Successfully found vanity address in 34 seconds.
Address: 0x00001bCd6F496eDbB5B45095801e8b17b02B0049
Private Key: 0xedbd9f7e259364837b982ea3742e1bd81956df90c713256ea928b7ee0c5b9312
```
:warning: ProfanityというVanity addressを生成する有名なツールに脆弱性がありました。秘密鍵生成ツールや生成方法にはバグがあった場合、資産の漏洩に直結します。コードをセルフauditするか、ツールの使用にはそのようなリスクが伴うことに留意するべきです。
[A vulnerability disclosed in Profanity, an Ethereum vanity address tool](https://blog.1inch.io/a-vulnerability-disclosed-in-profanity-an-ethereum-vanity-address-tool-68ed7455fc8c)

### 例3：16進数を10進数に変換したい
建てたノードが動作しているか確かめるために、`eth_blockNumber`を叩いてみたけど、レスポンスが16進数なので読みづらい！！いちいち、変換サイトを検索するのも億劫です。castで一発で変換できます。
```
> curl -X POST --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":51}' http://localhost:8585
{
  "jsonrpc" : "2.0",
  "id" : 51,
  "result" : "0xef6409"
}%   
```

```
> cast --to-dec 0xef6409                                                 
15688713
```
または
```
> cast block-number --rpc-url=$MAINNET_RPC_URL 
15688713
```


### 例4：Txnのトレースを見たい
テストのデバッグ時などトランザクションのトレースを見たい時ありますよね。 

試しに、Uniswapのガバナンストークンの送金トランザクションを見てみましょう。
有名な関数セレクタならシグネチャ`transfer(...)`のように変換されて表示されます。
```
> cast run --rpc-url=$MAINNET_RPC_URL 0x721dacc87c412b3a1cf5e3d8226a19a7cb0aff9c93167187e648dc05fa89e67c
Executing previous transactions from the block.
Traces:
  [18462] 0x1f98…f984::transfer(0x91161424a172b777e4c3883ffeb79cb53405a021, 69218200000000000000) 
    ├─ emit Transfer(param0: 0xee91ae665be6a92a1241911cea3cae9d50fe658d, param1: 0x91161424a172b777e4c3883ffeb79cb53405a021, param2: 69218200000000000000)
    └─ ← 0x0000000000000000000000000000000000000000000000000000000000000001


Transaction successfully executed.
Gas used: 40118
```

## 最後に
castコマンドラインツールはsmart contract開発におけるスイス・アーミーナイフです。

### 参考リンク
https://book.getfoundry.sh/reference/cast/
[Flutter] YouTubeのサムネイルを表示させたい


YouTubeのサムネイルを載せたいな！と思ったら、
下記のパッケージを使うと簡単に実現できるので便利。
https://pub.dev/packages/youtube


# インストール 
pubspec.yamlに記載して、Pub get
```dart
dependencies:
  youtube: ^1.0.1
```

# 使い方
importで呼び出します
```dart
import 'package:youtube/youtube_thumbnail.dart';
```
１行だけでサムネイルを表示させることができます
```dart
Image.network(YoutubeThumbnail(youtubeId: 'oR7lofyBj7k').small())
```
🔖 youtubeId・・・https://www.youtube.com/watch?v=?????????? の ??????????部分を指定する
🔖 .small()・・・ サムネイルの表示サイズを指定（下記５つの中から選ぶ）。
|サイズ|指定方法|
|:--:|:--:|
|1280x720|.hd()|
|640x480|.standard()|
|480x360|.hq()|
|320x180|.mq()|
|120x90|.defaults()|

# 応用
サムネイルをタップした時にYouTubeリンクへ飛ばしたい場合は・・・
```dart
InkWell(
  onTap: () async {
    await launchUrlString("https://www.youtube.com/shorts/oR7lofyBj7k");
  },
  child: Image.network(YoutubeThumbnail(youtubeId: 'oR7lofyBj7k').small()),
)
```

# デモ
<strong>環境</strong>
macOS Monterey 11.3.1
Flutter 3.3.1
Dart 2.18.0
youtube: 1.0.1

<img width="300" alt="IMG_2270.JPG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/98081/d2914b07-7800-f300-a9e2-2619f2c9c5ec.jpeg">

```dart
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher_string.dart';
import 'package:youtube/youtube_thumbnail.dart';

class Music extends StatefulWidget {
  const Music({Key? key}) : super(key: key);
  @override
  State<Music> createState() => _MusicState();
}
class _MusicState extends State<Music> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          children: [
            const Padding(
              padding: EdgeInsets.only(top: 50),
              child: Text(
                "Music",
                style: TextStyle(
                  decoration: TextDecoration.underline,
                  decorationStyle: TextDecorationStyle.double,
                  fontSize: 48,
                ),
              ),
            ),
            Padding(
              padding: const EdgeInsets.only(top:30, right: 10, left: 10),
              child: Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  InkWell(
                    onTap: () async {
                      await launchUrlString("https://www.youtube.com/shorts/oR7lofyBj7k");
                    },
                    child: Image.network(YoutubeThumbnail(youtubeId: 'oR7lofyBj7k').small()),
                  ),
                  const Padding(
                    padding: EdgeInsets.only(left:10),
                    child: FittedBox(
                      fit: BoxFit.fitWidth,
                      child: Text(
                        "2020/3/某日\nコロナ初期の星野源さんの『うちで踊ろう』"
                            "\n私も影響されてキーボードでセッションに参加",
                        style: TextStyle(fontSize: 12),
                      ),
                    ),
                  ),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }
}
```
整数を分解する方法

# 整数を分解するにはどうしたらよいのか？
rubyの問題を解いていて躓きましたので、備忘録として残します。

# 整数の分解の仕方
・１００の位の取得方法
```ruby 
(num / 100) % 10
```

・１０の位の取得方法
```ruby
(num / 10) % 10 
```
・１の位の取得方法
```ruby
(num / 1) % 10 
```
取り出したい数字の桁数で割り
その結果をさらに10で割った、そのあまりが任意の桁の数字となります。
※注意点
Rubyの性質上、整数同士（integer型）の計算だと返り値は整数になるので、小数点以下は切り捨てられます。

# 問題を解いてみよう
２桁の整数を入力させ、その１０の位と１の位を取得しよう
```ruby 
def slice_num(num)
  x = (num / 10) % 10 
  y = (num / 1) % 10
  return x, y
end
  
puts "二桁の整数を入力してください"
input = gets.to_i
x, y = slice_num(input)

puts "10の位は#{x}、1の位は#{y}である"
```

無事に分解することができました。
なお、returnでカンマで区切ることにより、複数の変数を同時に定義することができるとのこと。