OmniAICreator/Qiita-1.07M huggingface dataset:
AWS初心者がクラウドプラクティショナーを勉強して感じたメリット

# はじめに

つい先日、AWSクラウドプラクティショナーに合格して少し日が経過しました。

↓合格記事↓

https://qiita.com/draw_5050/items/47d13466daeb6863c8b2

筆者は去年(2021年初頭)まではAWSほぼ何も知らないひよっこで、
かろうじてS3が何なのか知っている程度で他のサービスはほぼ何もわからんみたいな状態でした。

そこから1年間、少しずつ業務でAWSに触れ始めはしましたが、まだまだ勉強不足を感じ
2022年に入り思い切って受験を決意した次第です。

この記事では、**AWS初心者の筆者がクラウドプラクティショナーを勉強した際に感じたメリット**、
そして「**そもそもクラウドプラクティショナーって取るべきなの？**」という疑問に対して
自分なりの回答を書きたいと思います。

# この記事の対象者

- AWSクラウドプラクティショナーを受験しようか迷っている方
- AWS初心者で勉強したいと思っている方

# 結論

最初に結論を書きます。

AWSクラウドプラクティショナーはAWSを勉強したい方は**是非取得すべき**だと思います。
IT系の資格は物によっては実務に活かしにくかったりしますが、
AWSクラウドプラクティショナーは**かなり即効性が高く**、AWSを採用している会社なら
勉強を進めていく過程でどんどん仕事を進めやすくなると思います。

それでいて基本情報技術者試験とかより難易度は全然低く、
割といつでも受験する事ができるのでハードルも低いです。情報もネット上に転がっています。

たまに「この資格あまり取っても意味ない」という意見は聞きますがそんなことはありません。
**試験難易度**と**そこから得られるもの**は決して比例しません。

# AWSクラウドプラクティショナーとは？

勉強して良かったことを話す前に一応この資格について説明しておきます。

https://aws.amazon.com/jp/certification/certified-cloud-practitioner/


> この資格は、組織がクラウドイニシアチブを実装するための重要な知識を
持つ人材を特定して育成するのに役立ちます。
AWS Certified Cloud Practitioner を取得することで、
クラウドへの理解と基礎的な AWS の知識が認定されます。

AWSにはいくつか認定資格が用意されており、この資格はその中でも最も基礎な部分に
位置づけられています。

![aws](https://d2908q01vomqb2.cloudfront.net/92cfceb39d57d914ed8b14d0e37643de0797ae56/2021/05/21/certs1-191-1024x540.png)

内容としても、そこまで専門的な事は聞かれず
**AWSの基本的な概念が頭に入っているか**に重きを置いています。
ですのでそもそも知っているかの覚えゲーが多くなる感じです。


# メリット1: AWS強者の言っていることがぼんやりわかるようになる

開発者が仕事を進める上での一番のメリットはこれだと思います。
例えばですが、

**「EC2とRDSを使って、EC2インスタンスは2台の冗長構成にしてELBでバランシングして、可用性上げるためにマルチAZ構成にして、ログを見るためにcloudwatch agentをインストールしてcloudwatch logsで見れるようにして、共通のファイルを読ませたいからEFSを採用して、アプリケーション毎にアカウント分けたいからorganizations使って…」**

みたいな横文字が大量に出る会話、強い人はいっぱいしていると思います。

AWSは独自の概念が多く、まずはそこを理解する必要があります。
サービスの種類も全体では200を超え、よく使う基本的なサービスだけでも数十個はあります。

クラウドプラクティショナーはその独自概念や基本的なサービスを
網羅的に勉強する事ができるので、まさに「何言ってるのかわからない」から脱するのにうってつけです。

さすがにクラウドプラクティショナーの段階では自力でAWSの構成を考えるのは難しいですが、
**AWS強者の言っていることがぼんやりわかるようになり、ある程度の意図は掴めるようになります。**

AWS周りの業務を進める上でかなりやりやすくなると思います。

# メリット2: 知らないサービスに対してのアレルギーが無くなる

クラウドプラクティショナーを勉強する際、大体の人は知らないサービスに
触れることになると思います。

知らないサービスに遭遇した際、自力で調べて情報収集をすると思うのですが
これが実務での非常に良いトレーニングになります。

実際、AWSを触っているとドキュメント漁りが続いたりするので
この資格勉強と一緒に調査の練習ができます。

こうして知らないサービスに触れていくうちに、
少しずつ慣れてきて知らないサービスに対しての抵抗感が無くなっていきます。

要するに**AWSを触る機会が増えるので慣れる**って訳です。
自力で知らないサービスを調査する力が身につきます。

# メリット3: 次の資格を取るモチベーションができる

拾い物ですが、下記画像のような感じになります。
![aws.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532812/c23cdf06-d61f-fccc-c2ab-e725dda06b2f.png)
クラウドプラクティショナーはAWSの全資格の基礎になっているので、
流れで勉強を進めれば1段階上の資格も狙えます。
筆者もSAA、SOA、DVAの3冠を狙っています。

合格すると自己肯定感が上がって、AWSの資格に限らず**自己学習のモチベーション**が上がります。
実際、合格したときの達成感は凄かったです。あれは**麻薬**です。


# 終わりに

AWSクラウドプラクティショナーは、入社したばかりで
「AWSわかんね～～～」となっている方にも非常にお勧めできる資格です。
是非取得を検討されてはいかがでしょうか。
【MySQL】定期的にmysqlのconnection数を確認する

# これは何？

業務でmysqlの接続数(connection数）を確認する場面があったので、

その際に使用した便利なコマンドを備忘録として記載する。

# 実行コマンド

実行コマンドは以下の通りでwatchコマンドとsqlを組み合わせるだけ

以下の例は3秒ごとにmysqlのコネクションを確認する。
```shell
watch -n ${INTERVAL_NUM} --differences \
"mysql mysql -h ${MYSQL_HOST} -u ${MYSQL_USER} -p${MYSQL_PASSWORD} -Be \
'select count(*), db from information_schema.PROCESSLIST group by db;'"

# example
watch -n 3 --differences \
"mysql mysql -h localhost -u root -proot -Be \
'select count(*), db from information_schema.PROCESSLIST group by db;'"
```
- `watch [オプション] コマンド`
  - コマンドを定期的に実行するためのコマンド
  - `-n <秒数>` : 何秒ごとに実行するか指定
  - `--differences` : 実行ごとの差分を表示


# 最後に

今回は mysqlの接続数を確認するときに便利なコマンドについて書いてみました。
なにか不明点などあれば、コメントお願いします。
Pythonで新規ファイル作成時にディレクトリが存在しなければ作成する方法


よく使用する便利な書き方なので備忘録として。


`os.makedirs`は`exist_ok=True`とすると、既に存在するディレクトリに対しては何もしない。
引数がディレクトリなので、pathが出力ファイルの場合は以下のように指定する。

```python
path = 'piyo/hoge/hoge.txt'
os.makedirs(os.path.dirname(path), exist_ok=True)
```

## 参考

https://note.nkmk.me/python-os-mkdir-makedirs/
AWS未経験者がAWS資格を取得するまでに行なったこと

## 背景
簡単に私の経歴を紹介。
1. プログラマーとして学生時代に2年ほどインターンに参加
1. 現在の会社（SIer）に入社後も主にアプリケーションの開発に携わる
1. AWS含むパブリッククラウドには触れたこともない

こんな私でもAWSの初級資格「AWSクラウドプラクティショナー」を取得できたので、資格取得までの流れをまとめる。

## 実施内容
1. AWS提供のEラーニングを試聴
⇨AWS提供のEラーニングを2週間かけて試聴（結構ダラダラ観てた）。いい意味で日本のEラーニングっぽくなくて最後まで楽しんで観れた。
1. Udemyの模擬試験問題集（7回分）を解く
⇨[Udemyの模擬試験](https://www.udemy.com/course/aws-4260/)を2週間かけて解いてみた。基礎2問、応用3問、発展2問あったが、基礎2問と応用2問しか解いてない。

以上の内容で試験を受験。結果は約750点とかなりギリギリだったが無事合格できた。応用まではしっかり解いておいた方が余裕を持って合格できるかも。
次回はソリューションアーキテクトアソシエイトを受験する予定。
Minicondaから構築してscikit-learn、Jupyter notebookまで

# 0.Intro

[ドメイン配下でのSambaの設定とADユーザーでのLinuxへのログインまで](https://qiita.com/hazigin/items/1842f7615a74e83d1ee2)で構築した環境に本来的な目的の機械学習環境を構築していきます。
そこで問題となるのがAnacondaの有償化です。社員が200人以下なら大丈夫のようだが幸か不幸かもう少し弊社は多い。
なので
[Anacondaの有償化に伴いminiconda+conda-forgeでの運用を考えてみた](https://qiita.com/kimisyo/items/986802ea52974b92df27)
を参考にさせて貰いながらまず最低限の環境を構築していきます。

要件は以下
1. condaで仮想環境を作って作業を行う。
2. まずはTableau dataからということでscikit-learnを扱える環境を構築。
3. Jupyter Notebookは必須。
4. そこにSSH接続でVSCode上で作業する


# 1.Minicondaの導入
本家からダウンロード
```
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
```

実行権限付与
```
sudo chmod +x Miniconda3-latest-Linux-x86_64.sh
```
インストール
```
bash Miniconda3-latest-Linux-x86_64.sh
```
イントールの最終で.bashrcも編集してくれるので読み込むだけ
```
source ~/.bashrc
```
プロンプトに環境が表示されるが一応確認
```
which conda
```
homeディレクトリを向いていたらOKかと

記事にあるようにdefaultのchannelを削除しないライセンス違反になるようなので
```
conda config --remove channels defaults
```
そして記事には無いがconda-forgeは(今は)自分で入れないといけないらしい
```
conda config --add channels conda-forge
```
これでconda環境が整ったのでpythonを入れて環境を作る。バージョンはkaggleに合わせて3.8とします。
```
conda create -n ml_env python=3.8
```
有効化
```
conda activate ml_env
```

以上でcondaでの仮想環境の構築完了。

# 2.必要ライブラリの導入
ライブラリを入れて目的の環境を作る。
バージョンは極力kaggle Dockerに合わせたつもりです。

**Jupyter Notebook**
```
conda install notebook ipykernel
```

**何は無くともPandas**
```
conda install pandas==1.3.5
```

**目的のscikit-learn(一緒にnumpyも入った)**
```
conda install scikit-learn==0.23.2
```
**EDAに必須**
```
conda install matplotlib
```

# 3.VS CodeでSSH
この辺はネットに有益な記事が多々あるのでそちらに譲ります。

[VSCodeからSSH接続をする方法](https://www.server-memo.net/memo/vscode/vscode_ssh.html)

Python用拡張機能もがっつり入れないといけませんが凡そ自動化されているので迷うことはほぼ無いですね。ただ初回は非常に時間かかりました。マシンが古くてHDDがへたっているせいでしょうか。

[【リモート開発】vscodeにPython拡張機能のインストール](https://self-development.info/【リモート開発】vscodeにPython拡張機能のインストール)


# 4.完了
以上で機械学習社内勉強会用の環境が出来上がりました。
先ほどテスト的に簡単な分類問題を流してみました。上記の拡張機能のインストールが絶望的に遅かったので心配しましたが、思ったより快適かもしれません。
とりあえずメンバーに公開し、あれこれ弄ってもらいつつ、環境を成熟させつつ勉強に励みたいと思います。
ドメイン配下でのSambaの設定とADユーザーでのLinuxへのログインまで

# 0.Intro
　会社で機械学習の勉強会を行うにあたり、貸与されている事務用の8GメモリのWindowsマシンだけではなかなか辛いものがあるので、一台昔サーバー的に使っていて引退した24Gメモリのマシンが空いていたので共有で使うことにしました。社外秘のデータも扱いたいのでローカルに構築したかったというのもあります。
環境構築するにあたっての必要要件としては
1. ライセンスフリーで機械学習環境に最適なLinux環境で構築。但しLinuxに不慣れなメンバーもいるので出来るだけ意識しないで済むように。
2. Sambaで共有フォルダを設定、但しアクセス制御は必須。

があります。
まず上記二点を満たす環境をつくることにしました。

OSは**Ubuntu Server 20.04**にしました。

# 1.ドメイン参加
いつもお世話になっております、[Server World](https://www.server-world.info/query?os=Ubuntu_18.04&p=samba&f=3)様のお知恵をお借りして。

```
sudo apt -y install winbind libpam-winbind libnss-winbind krb5-config samba-dsdb-modules samba-vfs-modules
```
Kerberosは説明の通りに設定。

ドメインに参加の手順まず困りました。
```
net ads join -U [AD の管理者ユーザー]
```
でADが見えないと。
いろいろ確認すると　/etc/resolved.conf　に書いたADのIPが消えていたので追記しました。
その後無事ADに参加できました。
```
wbinfo -u
```
も結果が得ってきました。

色々その他設定を行い、でもまた手詰まり。確認のために
```
wbinfo -u
```
を行うも返ってこず。
確認したところ
/etc/resolved.conf　に書いたADのIPがまた消えていました。

# 2.DNS(AD Server)の設定について
サーバーなのでIP固定としており
```
/etc/netplan/00-installer-config.yaml
```
に
```
nameservers:
 addresses: [192.168.1.1]
 search: []
```
という形でしてDNS(AD Server)は記載しています。基本はこれだけで良さそうなものですが、Winbindには足りない様子。
調べてみるとUbuntu 17.04以降は **/etc/resolved.conf** ではなく、**systemd-resolved**とのことで
```
/etc/systemd/resolved.conf
```
書き換え
```
sudo systemctl restart systemd-resolved.service
```
とsystemd-resolved 再起動しました。

でもADに聞きに行ってくれません。
またresolved.confにADのIPを列記。でも再起動してまた消える。
消えるのでWinbindが動いてくれない。

結局
```
sudo systemctl stop systemd-resolved
sudo systemctl disable systemd-resolved
sudo /etc/resolved.conf /etc/resolved.conf.bak
sudo vi /etc/resolved.conf
```
と、つまり自作することで解決としました。

systemd-resolvedには何やらバグがあるとの情報もありましたが、Winbindに/etc/resolved.confを直接見に行くみたいな仕組みがあり今のバージョンと非互換になっているか、その辺かなぁとも。
とてもハマったので、この悪戦苦闘を記載したく、本記事を書かせてもらっているようなものです。

# 3.ログイン後
無事にADのユーザーでUbuntuにログインも出来、SambaもADユーザーで共有フォルダを見に行くことが出来、valid userにてアクセス制御も出来ました。
設定の中で
```
winbind use default domain = true
```
を有効にするか向こうにするかは少し考えました。
valid userを指定するときに
```
valid users = "DOMAIN\YYYYXXXX","DOMAIN\ZZZZAAAA","DOMAIN\BBBBCCCC"
```
とすればアクセス制御も効いたのでよかったのですが、やっぱり
```
valid users = "YYYYXXXX","ZZZZAAAA","BBBBCCCC"
```
としたの方がシンプルなのと、ADユーザーでログインして使うことにしたので、操作の時にユーザー名のところにいちいちドメインが表示されるのが煩わしかったので結局
winbind use default domain = true
と有効化することにしました。

# 4.ADユーザーでsudo
sudoを使えないと困るので
[Active Directoryドメインに参加させたCentOS8で、Domain Admins所属ユーザーにsudoを許可する](https://qiita.com/otagaisama-1/items/4d16e592c172d65cc6e1)
こちらを参考にさせて頂きました。こちらはCentOSでされているとのこと。
そのままだとUbuntuでは使えませんでした。
Ubuntuでは以下でした。
```
%domain\ admins ALL=(ALL) ALL
%domain\ user ALL=(ALL) ALL
```
こちらで無事にsudo出来るようになりました。

ここまででやっと素地が出来ました。この上に機械学習環境を構築していくことになります。
Microsoft PowerBI Desktopで、グラフの目盛りに余分な日にちを表示させない

記載日：2022/4/7
PowerBI Desktopで、グラフに余分な日にちが表示されてしまうことがありました。
軸の設定をすることで解決できたので、備忘録として記載します。

#### 目標
グラフの目盛りに余分な日にちを表示させない。

#### 課題
　例えば以下のように年のグラフを作ると、月が表示されたり半年ごとに目盛り表示されてしまったりすることがある。
　本当は目盛りには年のみが表示してほしい。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1381309/bd1fd726-f730-32d0-6746-b31b8405e0b9.png" width=80%>

#### 解決策
　画面右側の”視覚化”の”軸”欄で、下矢印を押すと選択肢が表示される。
　その中で、”[カラム名]”と”Date Hierarchy”のどちらかにチェック（レ）をつけることができるので、チェックを切り替えることで余分な日にちを消すことができる。
　例えば、本グラフの場合は、”Date Hierarchy”にチェックをつけ、さらに月日といった余分な項目を削ることで、希望する表示を実現できた。

　・変更後
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1381309/a0a6b70b-c0de-cd14-12c1-48bc403d8fce.png" width=100%>

　・変更前
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1381309/f8273c0c-ef8b-b746-ec7b-25ec198d51e9.png" width=100%>
【統計検定準1級対策①】離散一様分布の確率関数，期待値，分散，母関数の導出過程

## 結論
>確率関数
>```math
>f(x) = 
>\frac{1}{K}\ \  (x = 1,2,\cdots,K)
>```
>期待値，分散
>```math
>E[X] = \frac{K+1}{2}, \ \ V[X] = \frac{K^2-1}{12}
>```
>母関数
>```math
>G(s) = \frac{s+s^2+\cdots+s^K}{K} = \frac{s(1-s^K)}{K(1-s)}
>```
## 期待値の導出

期待値の定義：$\displaystyle E[X]=\sum_{x}xf(x)$を思い出して，
```math
\begin{align*}
E[X] &= 1\cdot\frac{1}{K} +2\cdot\frac{1}{K} +\cdots + K\cdot\frac{1}{K}\\
&= \frac{1}{K}\cdot(1+2+\cdots+K)\\
&= \frac{1}{K}\cdot\frac{1}{2}K(K+1)\\
&= \frac{K+1}{2}
\end{align*}
```

## 分散の導出
分散は偏差の２乗の期待値 $\left(\displaystyle V[X]=E[(X-\mu)^2]\right)$ だから，
```math
\begin{align*}
V[X] &= E[(X-\mu)^2]\\
&= \sum_{x}(x-\mu)^2f(x)\\
&= \sum_{x=1}^{K}\left(x-\frac{K+1}{2}\right)^2\frac{1}{K}\\
&= \left(\sum_{x=1}^{K}x^2 - (K+1)\sum_{x=1}^{K}x + \frac{K(K+1)^2}{4} \right)\frac{1}{K}\\
&= \left(\frac{1}{6}K(K+1)(2K+1) - \frac{1}{2}K(K+1)^2 + \frac{1}{4}K(K+1)^2 \right)\frac{1}{K}\\
&= \frac{1}{6}(K+1)(2K+1) - \frac{1}{2}(K+1)^2 + \frac{1}{4}(K+1)^2\\
&= \frac{1}{12}(K+1)(K-1) = \frac{K^2-1}{12}\\
\end{align*}
```

【別解】
関係式：$V[X]=E[X^2]-(E[X])^2$ から，
```math
\begin{align*}
V[X] &= E[X^2]-(E[X])^2\\
&= \sum_{x=1}^{K}x^2f(x) - \left(\frac{K+1}{2}\right)^2\\
&= \frac{1}{6}(K+1)(2K+1) - \frac{1}{4}(K+1)^2\\
&= \frac{1}{12}(K+1)(K-1) = \frac{K^2-1}{12}
\end{align*}
```
## 母関数の導出
確率母関数の定義：$G(s)=E[s^X]$ から，
```math
\begin{align*}
G(s) &= E[s^X]\\
&= \sum_{x=1}^{K}s^x\frac{1}{K}\\
&= s\frac{1-s^K}{1-s}\frac{1}{K} = \frac{s(1-s^K)}{K(1-s)}
\end{align*}
```

## まとめリンク
[【統計検定準1級対策】確率分布の確率関数，期待値，分散，母関数まとめ
](https://qiita.com/matsuda-blog/items/4573b08f75b3d3c49c16 "すべての主要確率分布まとめ")
npmとyarnって何？結局どっちがいいの？？？


# はじめに
業務や趣味開発をしていくうちにごっちゃになってしまったので、一旦簡単にではありますが、まとめてみることにしました。

本記事は、以下のような方たちを対象に執筆します。
- <strong>パッケージ管理ツール</strong>ってなんぞ？な方
- <strong>npm</strong>と<strong>yarn</strong>って聞いたことあるけど違いが判らんなぁ。って方

筆者は上記の対象に当てはまりますので、本記事を書き上げて知識に定着させたい所存です👼

# パッケージ管理ツールとは
まず、<strong>パッケージ</strong>とは、様々なシーンで活用するために作成されたプログラムのかたまりを指しています。
そして、<strong>パッケージ管理ツール</strong>（パッケージマネージャー）とは、特定のシステム（言語）環境の中で、パッケージを管理するためのツールです。

### パッケージの管理
- パッケージの導入
- パッケージの削除
- パッケージのバージョン管理
- パッケージ同士の依存関係を整理

といったことが挙げられます。
また、npmだとパッケージの管理のために、package.jsonとpackage-lock.jsonが作られますね。

パッケージ管理ツールは、システムや言語の数だけ存在すると思った方がいいでしょう。PHPなら「composer」、Pythonなら「pip」...といった感じです。それぞれ使い方が違うと思いますので、必要に応じて調べましょう。

これについては、以下の記事が参考になりそうです。
- [バージョン管理ツール、パッケージ管理ツールの種類をまとめました](https://qiita.com/akkey2475/items/5b2813e62303a9c75813)

# npmとyarnの違いって何？
来ました本題です。npmとyarnの違いについて。
npm及びyarnは、どちらともJavaScript(Node.js)のパッケージを管理するためのものです。
何も考えず利用する分には一緒ですが、細かな部分が違うみたいです。

### npmは...
- 2010年にnpm社がリリース（2020年にGithub社が買収）
- 公式のパッケージマネージャー
- WindowsなどでNode.jsをインストールすると一緒に付いてくる
- package-lock.jsonがロックファイル（v7以降）

#### コマンド例
```
/*** 昔はこんな感じ。 ***/
npm install --save foo
npm install --save-dev foo

/*** 最近はこんな感じでもOK ***/
npm i foo
npm i -D foo
```

### yarnは...
- 2016年にFacebook社がリリース
- 非公式のパッケージマネージャー
- パッケージをインストールする速さが魅力
- npmを介してインストールを行う
- yarn.lockがロックファイル

#### コマンド例
```
yarn add foo
yarn add --dev foo
```

## どちらがよく使われているのか？
見た感じ、yarnの方が人気がありそうです。
2022年時点ではnpm側が改善を重ねたことで、大きな差は無くなったようです。
### 過去にyarnが使われた主な理由
- yarnのほうがコマンドが簡潔（後にnpmのほうが簡潔になった）
- インストール速度がyarnのほうが早い
- npmがv7になるまで、yarnにしかロックファイルが存在しなかった
- yarnにのみ存在する独自機能

インストール速度については、2022年時点もyarnが勝っているようです。
とはいえ、単純に利用することのみを考えると、完全にお好みで選べば良いという感じがします。

## 筆者の中での結論
<strong>好きな方を選ぶことにします。</strong>
筆者の場合は元々npmを使っていたので、趣味開発ではnpmを使いつつ、業務で必要に応じてyarnに切り替える感じでよさそうです。
とはいえ、これらは日々変わるものですので、常に情報のキャッチアップを欠かさないよう気を付けます。

ちなみに、<strong>npmからyarnに切り替えたい！</strong>って人は、以下のコマンドを使うことで、package-lock.jsonをyarn.lockに移行できるみたいです。
```
yarn import
```

# 終わりに
最終的には引き分けみたいになっちゃいましたが、パッケージ管理について、npmとyarnのそれぞれの特徴について、理解を深める良い機会になりました。よくよく考えたら、React等より真っ先に理解すべき内容でした。順番間違えちゃったなぁ～～。

# 余談
最近業務で<strong>Homebrew</strong>を使う機会があり、こっちも「何これ？？」ってなったので調べました。

### Homebrewとは
- npmと同じパッケージ管理ツール
- macOS上で動作する
- これさえあればgitやMySQLもコマンド一つでインストール可能！ぽい
- パッケージは実体とエイリアスが対応した場所に保存される
- 実体のデフォルトインストール先 (/usr/local/Cellar)
- エイリアスのデフォルトインストール先(/usr/local/bin)

#### インストールコマンド
```
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
```

#### パッケージの追加
```
brew install パッケージ名
```
何だこれって思ってたけど、感覚はnpmと似てるのかな。まだわかんないことだらけなので、今度調べよ～～

# 参考サイト
- [npmとyarnとpnpmの違い2021](https://zenn.dev/hibikine/articles/27621a7f95e761)
- [npmとは yarnとは](https://qiita.com/Hai-dozo/items/90b852ac29b79a7ea02b)
- [バージョン管理ツール、パッケージ管理ツールの種類をまとめました](https://qiita.com/akkey2475/items/5b2813e62303a9c75813)
- [yarnとnpmの栄枯盛衰](https://blog.ikeryo1182.com/yarn-and-npm/)
- [【JS】yarnの長所とyarnからnpmに戻ってきた理由](https://jsnotice.com/posts/2020-09-02/index.html#%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%81%AFnpm%E3%81%AE%E6%96%B9%E3%81%8C%E7%B0%A1%E6%BD%94%E3%81%BE%E3%81%A7%E3%81%82%E3%82%8B)

今回もたくさんのサイトを参考にさせて頂きました。ありがとうございました。:bow:
ShopifyをGitHubで管理する。


shopifyは管理画面からコードを変更することが可能ですが、GitHubとの連携でより開発しやすくなったので、その備忘録。

# 課題

1、管理画面からの編集では、いつ、誰が、何を、変更したのかの履歴が残らない。
2、同時編集による先祖返りが起きる可能性がある

# 手順
1、shopifyとGitHubを連携
![スクリーンショット 2022-04-07 20.17.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2583836/69a4d426-5cdb-ae37-2a3e-3331f138402c.png)

2、管理画面のテーマライブラリーを３つ作成します。
- develop（開発用）
- main（確認用）
- phase1（公開用）

![スクリーンショット 2022-04-07 21.20.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2583836/dcf791bd-3397-d829-9f7e-3baa512db365.png)

develop（開発用）で開発を行い、main（確認用）にmargeして、テーマで確認:point_up:
develop　→ main 

また、他の人が管理画面から触る場合はphase1（公開用）が更新されるので、
開発前にmain（確認用）へmargeさせ、さらにdevelop（開発用）へ戻してから作業すること:point_up:
phase1（公開用）での変更は、main（確認用）、develop（開発用）では反映されないので、注意！
phase1→main→develop

リリースの際はmain　→　phase1　へmargeして、公開!!:point_up:

ではまた。
Dockerでapt-get updateするとエラーになる

## 概要
docker-で環境構築中にdocker-compose build押すとapt-get updateでコケる現象があった。

```
#10 2.636 E: Release file for http://security.debian.org/debian-security/dists/bullseye-security/InRelease is not valid yet (invalid for another 3h 27mi
n 14s). Updates for this repository will not be applied.
#10 2.636 E: Release file for http://deb.debian.org/debian/dists/bullseye-updates/InRelease is not valid yet (invalid for another 6h 41min 1s). Updates
for this repository will not be applied.
```

## エラー原因
WSL内の時間が実際の時間とずれていると起きるエラーらしい。

＝＝環境＝＝＝
Windows 10 Home
WSL2 (Ubuntu-20.04)

## 対処方法
Windowsのpowershellを開き、下記コマンドを流してWSLを再起動するだけ。
※shutdownとなっているが、wslは自動で再起動されるので実質再起動コマンドになる

ちなみに1秒くらいで終了するので、すぐ解消できる
```bash
$ wsl --shutdown
```

## 余談
Docker側も再起動しないと以下のようなエラーが出る場合がある。

```
$ docker-compose build
error during connect: This error may indicate that the docker daemon is not running.: Get "http://%2F%2F.%2Fpipe%2Fdocker_engine/_ping": open //./pipe/d
ocker_engine: The system cannot find the file specified.
```

Dockerをrestartすれば解消される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308656/2dc1314f-57f7-1877-0564-bfbfd0d135f3.png)

以上となります。
配列の要素を削除、減らす　JavaScript

## 用途
- 配列の要素を削除したい時、要素を減らしたい時に使用する。

## 使用方法

## shift
```js:書き方
配列名.shift();
```
配列の先頭の要素を削除し、残りの要素を戻り値として返す。
配列が元から空だった場合は `undefined` を返す。
残っている要素についてはインデックスが1つずつ小さくなる。
```js:例
var hoge = ["hoge1", "hoge2", "hoge3"];
hoge.shift();

console.log(hoge);
結果
["hoge2", "hoge3"]

console.log(hoge[0]);
結果
hoge2

console.log(hoge.shift()) // 削除した値を取得
結果
hoge1
```
配列の先頭の要素を削除し、残りの要素のインデックスが1つずつ小さくなった。

## pop
```js:書き方
配列名.pop();
```
配列の末尾の要素を削除し、残りの要素を戻り値として返す。
配列が元から空だった場合は `undefined` を返す。
```js:例
var hoge = ["hoge1", "hoge2", "hoge3"];
hoge.pop();

console.log(hoge);
結果
["hoge1", "hoge2"]

console.log(hoge.pop()) // 削除した値を取得
結果
hoge3
```
配列の末尾の要素が削除された。

## length
```js:書き方
配列名.length = 指定したい数の数値;
```
「指定したい数の数値」の数だけ、要素を戻り値として返す。
```js:例
var hoge = ["hoge1", "hoge2", "hoge3", "hoge4"];
hoge.length = 1;
console.log(hoge);
結果
["hoge1"]

hoge.length = 2;
console.log(hoge);
結果
["hoge1", "hoge2"]

hoge.length = 0;
console.log(hoge);
結果
[]
```
指定した数の要素が返される。（先頭から数える）
 
 
 
 
下記の記事を参考にしました。
- https://www.javadrive.jp/javascript/array/index8.html
OSI参照モデル -物理層について-

OSI参照モデルにて勉強しているため、勉強したことをQiitaに投稿していきます。今回は物理層について投稿します。
## OSI参照モデルとは
まず、OSI参照モデルとは、国際標準化機構（ISO）より策定されたコンピュータなどの通信機器の通信費を、７階層に分けたモデルのことである。
第7層：アプリケーション層
第6層：プレゼンテーション層
第5層：セッション層
第4層：トランスポート層
第3層：ネットワーク層
第2層：データリンク層
第1層：物理層
上記のように分かれており、この7つの階層にはそれぞれの階層で行われている通信機能を定義している

OSI参照モデルにより、ネットワーク全体でどのようなデータのやりとりが行われているのか、わかりやすくなっている。

## 物理層とは
物理層はOSI参照モデルの第1層のこと。
ビット列のデータを電気信号として送る、電気信号で送られてきたデータをビット列に変換する階層であり、ハブやリピータが利用される機器である。

## リピータとは
リピータは電気信号における中継役であり、電気信号を受信し、弱まったノイズを増幅したり、整形したりする機器。

## 主な役割
物理層の説明でも記載したが、「ビット列のデータを電気信号として送る、電気信号で送られてきたデータをビット列に変換する」のが物理層のお仕事である。

データを転送するには、LANケーブルや光ケーブルなどあるが、電気信号でやりとりしている。

ただ、パソコンなどの機器は電気信号ではなくビット列（01010101のような0と1でできたもの）でやりとりしたいため、物理層で電気信号をビット列に変換している。

逆にデータを送りたい場合は、ビット列で整形して送信するが、LANケーブルなどは電気信号でやりとりしたいため、ビット列から電気信号に変換している。

## 次回予告
次回はデータリンク層について投稿予定。

## 参考文献
https://www.infraexpert.com/study/networking3.html

https://www.seraku.co.jp/tectec-note/industry/physical-layer/#:~:text=%E7%89%A9%E7%90%86%E5%B1%A4%E3%81%AFOSI%E5%8F%82%E7%85%A7,%E3%81%95%E3%82%8C%E3%82%8B%E3%81%93%E3%81%A8%E3%81%8C%E5%A4%9A%E3%81%84%E3%80%82
rex0220 アクション表示制御プラグイン アクションボタンの色を変えてみよう

[アクション表示制御プラグイン](https://qiita.com/rex0220/items/75b741747689c79db4cc)で、アクションボタンの色を指定する機能が追加されました。
簡単なプラグイン設定で、アクションボタンの色を変えられます。

# 概要

アクションボタンがいくつか並んでいると、文字だけだとわかりにくくて、操作ミスをしがち。
ボタンの色を変えるだけで、わかりやすさがアップします。

![2022-04-07_20h51_54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/0b263da1-5b33-ee5f-51e6-6384bb233ee7.png)

![2022-04-07_08h56_54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/859e16a1-b33d-77fd-b333-8082b40ad20e.png)


# アクション表示制御プラグインの設定

- テーマ欄をクリックして、カラーパレットで色を選択すると、文字色と背景色が設定されます。
- 文字色と背景色を別々に指定も可能です。
- 「運用環境に反映」をチェックして「保存」すると、本番環境に反映されます。

※表示条件を指定すれば、条件によって不要なアクションボタンを非表示にできます。
![2022-04-07_21h16_10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/f9ef4f62-a021-4fae-76b8-56625ce89bef.png)

# プラグイン設定と表示例

![2022-04-07_20h49_28.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/48d32d3d-6010-58cf-c591-e9b9dad30fc4.gif)
AWS 認定セキュリティ – 専門知識試験の受験記録

久しぶりにAWSの試験を受けてきました。
前回、受けた時に比べると、試験関連の本が多く出版されていたり、公式のトレーニングや問題集などが充実していて、勉強しやすくなっていると感じました。

## 学習内容

### 1. 公式サイトで確認
https://aws.amazon.com/jp/certification/certified-security-specialty/

こちらに、試験範囲やトレーニング動画、サンプル問題、模擬試験など一式そろってるので、まずはこちらを確認しました。

### 2. 書籍で学習
https://www.amazon.co.jp//dp/4839970947/

今までは、試験を受ける時点で、それに対応した本が出版されていなかったので使わなかったのですが、今回はあったので買って読んでみました。
他の方も書かれていますが、大変わかりやすく勉強になりました。

### 3. 問題を解く
https://www.udemy.com/course/amazon-aws-security-specialty-practice-exams-2021/

の問題集（25問×6回分）と、公式サイトのデジタルトレーニングの問題（24問）、本の問題（40問）を何度も繰り返し、解答を見てもあいまいな問題は、本やサイトで調べるなどしました。ほぼ全問解けるようになってから、公式サイトの模擬試験（20問）を解いたところ、正答率7割という微妙な結果だったので不安になりました。

## 試験振り返り
若干、自信がない中で受験したのですが、なんとか803点で合格できました。
問題集等では、あまり出題がなかったCloudHSMやSecurityHubに関する問題も出ていたので、試験範囲のサービスに関しては一通り学習しておいた方がいいと思いました。
コンタクトセンターのオペレータが問合せ内容をみるときに、英語や韓国語へ翻訳した状態で見たい。Dynamics 365 Customer Service から Microsoft Translator を呼び出す

今回設定するアプリはDynamics Customer Service アプリ ↓図の赤枠
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367026/28098b05-a4f0-4d30-bdc6-5075fbc42986.png)

## やりたいこと
コンタクトセンターのオペレータが問合せ内容をみるときに、英語や韓国語へ翻訳した状態で見たい

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367026/d3a005db-30ad-f8a1-6f84-3afcdc0c6070.png)

## システム構成図とカスタマイズ内容

テーブル作成や更新をトリガーに、Power Automateでデータ取得。
Microsoft Translator で翻訳し、テーブルを更新

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367026/df524b1a-0597-e81d-12ed-77fa46c5dec6.png)

## こちら使いました。Microsoft Translator コネクタ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367026/66ba2776-86bd-55fa-38dd-24aee3c40ed0.png)


## 設定手順
### 1.テーブル更新後に項目を変換するフローを作成する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367026/7bcf4a9b-bdef-fb79-69db-de92828084c8.png)

以上

## はまった箇所
登録したDataverseの行IDをPower Automateで取得し、更新処理をしたい。
どの項目がユニークIDかぱっとみわからない。

→解決しました。Case（サポート案件のユニークキーどれ？となる場合は、説明欄を読むことで把握できる）ユニークキーとなるIDは設定時の説明欄に記載あり。赤枠を読むことでユニークと判断できる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367026/37708941-1640-8fd9-0f41-cac4b2bbadb7.png)



## 本番運用で使う場合の対応方法（フロー制限引っかかる恐れがあるため）
実際は、翻訳したい場合だけに、更新処理を行うようにフラグかなにかの画面項目を1つ用意し、
フローにフラグがONであれば翻訳をする流れを行うのがよい。
※本番利用する場合は、事前に検証を行う必要あり、条件によってはすぐフロー回数の上限回数に達しフロー停止となるため。

## 全体フローの内容メモ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367026/7b1fa949-7f36-1102-2e35-a486645fce18.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367026/6dd217d8-42a6-a074-fcb9-f758194743b9.png)


## 参考URL
Docs Power Apps から Microsoft Translator に接続する

https://docs.microsoft.com/ja-jp/power-apps/maker/canvas-apps/connections/connection-microsoft-translator

こちら使いました。Microsoft Translator コネクタ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367026/66ba2776-86bd-55fa-38dd-24aee3c40ed0.png)


### ↓とても参考になりました。ありがとうございます。

https://www.teijitaisya.com/power-automate-translate/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367026/b385c6ea-6375-b130-c09f-cdbb2940ab41.png)



以上（執筆15分）
OBS｜音楽用キーボードでスイッチング

<iframe width="560" height="400" src="https://www.youtube.com/embed/jIsr2-2168Y" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

nanoKEY2 Switcher - https://youtube.l8r.jp/MidiSwitcher.html
obs-websocket 4.9.1 - https://github.com/obsproject/obs-websocket/releases/tag/4.9.1

```html:NanoKey.html
<!DOCTYPE html>
<html lang="ja"><head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<title>NanoKey</title><script>

$(e=>{
	$('body').append($('<ul id="log">'))
	var obs = new Switcher()
	new NanoKey().message(e=>{
		$('#log').prepend($('<li>').append(JSON.stringify(e)))
		var i = 'CDEFGAB'.indexOf(e.note)
		if(i>-1){
			switch(e.type){
				case 'NoteOn'	:obs.switch(i);break
				case 'NoteOff'	:obs.switch(0);break
			}
		}
	})
})

class NanoKey{
	constructor(){
		this.notes	= 'C,C#,D,D#,E,F,F#,G,G#,A,A#,B'.split(',')
		this.type	= {0x80:'NoteOff',0x90:'NoteOn'}
		this.hook 	= {}
		this.message(e=>{})
		navigator.requestMIDIAccess().then(r=>{
			console.log(r)
			r.inputs.forEach(v=>{
				v.onmidimessage = e=>{
					if(this.type[e.data[0]]) this.dispatch(...e.data)
				}
			})
		},console.log)
	}
	message(f){this.hook.message = f;return this}
	dispatch(type,noteNumber,velocity){
		var n = this.notes[noteNumber%12]
		var o = Math.floor(noteNumber/12)-1
		this.hook.message({
			type	: this.type[type],
			note	: n,
			octave	: o,
			key		: n+o,
			code	: noteNumber,
		})
	}
}

class Switcher{
	constructor(url){
		this.scenes		= []
		this.history	= {}
		var w = this.client	= new WebSocket(url||'ws://localhost:4440/')
		w.onopen = e=>{
			this.send(new Switcher.GetSceneList().then(r=>{
				if(r.status=='ok') this.scenes = r.scenes
			}))
		}
		w.onmessage = e=>{
			var v = JSON.parse(e.data)
			if(this.resolve(v)) e.stopImmediatePropagation()
		}
	}
	switch(i){
		if(this.connecting==false)	return this
		if(this.scenes[i]==null)	return this
		return this.send(new Switcher.SetCurrentScene(this.scenes[i]))
	}
	send(e){
		if(this.connecting==false)	return this
		this.history[e['message-id']] = e
		this.client.send(JSON.stringify(e))
		return this
	}
	resolve(e){
		var k = e['message-id']
		if(this.history[k]==null) return false
		this.history[k].resolve(e)
		delete this.history[k]
		return true
	}
	get connecting(){
		if(this.client==null) return false
		return this.client.readyState==WebSocket.OPEN
	}
}

Switcher.Request = class SwitcherRequest{
	constructor(e){
		this['message-id'] = this.random()
		Object.assign(this,e)
	}
	then(f){this.resolve=f;return this}
	resolve(){}
	random(){return Math.random().toString(36).substring(2)}
}
Switcher.GetSceneList = class extends Switcher.Request{
	constructor(){super({
		'request-type'	: 'GetSceneList'
	})}
}
Switcher.SetCurrentScene = class extends Switcher.Request{
	constructor(v){super({
		'request-type'	: 'SetCurrentScene',
		'scene-name'	: v.name,
	})}
}

</script>
</head></html>
```
【初心者向け】GitHub Copilot Labsの導入でつまずいたら

最近話題のGitHub Copilot Labs。
Visual Studio Codeの拡張機能で、これを使うとコードの解説や提案、他言語への翻訳までしてくれるとのこと。

https://next.github.com/projects/copilot-labs/

先人が書いたコードを眺めるものの何が書いてあるかさっぱりわからず検索しまくっている身としては、こんなにありがたいものはないと思い早速導入しようと思ったところつまずいたため記事にします。

まずはGitHub Copilot Labsの一般的な導入方法について。
GitHub Copilot LabsはVisual Studio Codeの拡張機能なので、他の拡張機能同様にVS Codeからダウンロードします。
この際、GitHubとの連携を求められます。

無事にダウンロードできるとサイドバーにウインドウができて操作できるようになるのですが、任意のコードを選んで「Ask Copilot」をクリックするとエラーが！！
![エラーが！.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2051906/e19ea8cf-5132-1cdd-5bca-008eeb5c0477.png)

エラーメッセージは、

:::note alert
Error generating Copilot response, please try again. Changes in the prompt or stop sequence might fix this.
:::

:::note info
(DeepLによる翻訳)
Copilotの応答生成にエラーが発生しました。プロンプトまたは停止シーケンスを変更すると、解決する場合があります。
:::

とのことも意味がわからず、、

いろいろ調べてみたら、GitHub Copilot Labsを使うにはGitHub CopilotのTechnical Previewに承認されているアカウントでログインしている事が必須ということで、これがエラーの原因と考えました。

GitHub CopilotのTechnical Previewへの順番待ちは、こちらから可能です。

https://github.com/features/copilot/signup

Qiitaを書き慣れたエンジニアの皆さんは、GitHub CopilotのTechnical Previewに承認されていることが多いため同様のエラーが生じない一方で、私のような初心者はつまづいて困ることもあるのではないかと考えて記事にした次第です。

GitHub CopilotのTechnical Preview承認には数ヶ月かかることもあるようなので気軽に待ちますー

## 4月9日追記
GitHub CopilotのTechnical Previewに関して、申請して2日後には承認が送られてきました。
そして、GitHub Copilot Labsは無事に使えました！
シリンダー要求動作速度から電磁弁サイズを概算



| シリーズ | マニホールド型番 | P、Rポート | 音速コンダクタンス[d㎥/(s*bar)] | 
| -------- | ---------------- | ---------- | ------------------------------- | 
| SYJ1000  | JJ5SY1-40        | 1/8        | 0.63                            | 
| SYJ3000  | JJ5SY3-40        | 1/4        | 1.81                            | 
| SYJ5000  | JJ5SY5-40        | 3/8        | 3.72                            | 
| SY3000   | SS5Y3-42         | 1/8        | 0.75                            | 
| SY5000   | SS5Y5-42         | 1/4        | 1.9                             | 
| SY7000   | SS5Y7-42         | 1/4        | 3.0                             | 
| SY9000   | SS5Y9-43         | C12        | 6.4                             | 
| VQ1000   | VV5Q11           | C8         | 0.85                            | 
| VQ2000   | VV5Q21           | C10        | 2.2                             | 
| VQ4000   | VV5Q41           | 1/2        | 7.2                             | 
| VQ4050   | VV5Q45           | 1/2        | 7.2                             | 
| VQ5000   | VV5Q51           | 3/4        | 17                              | 
| VQ5050   | VV5Q55           | 3/4        | 17                              | 

| シリーズ | マニホールド型番 | P、Rポート | 音速コンダクタンス[d㎥/(s*bar)] | 
| -------- | ---------------- | ---------- | ------------------------------- | 
| 4F2      | ---------        | ---        | 2.5                             | 
| 4F3      | ---------        | ---        | 3.9                             |
| 4F4      | ---------        | ---        | 5.0                             |
| 4F5      | ---------        | ---        | 9.7                             |
| 4F6      | ---------        | ---        | 15.0                            |
| 4F2      | ---------        | ---        | 2.5                             | 
| 4F4      | ---------        | ---        | 5.0                             |
| 4F5      | ---------        | ---        | 9.7                             |


単位の[d㎥/(s*bar)]が気持ち悪いまま長いこと使ってるので調べた。mm³/s*paと同じに扱えそう。
音速コンダクタンスについて ISO6358に規定がある。
[京都大学工学部物理工学科の講義資料](http://www.nucleng.kyoto-u.ac.jp/people/ikuji/edu/vac/app-A/conduct.html)　高木 郁二教授作成
流量Q = 音速コンダクタンス C[d㎥/(s*bar)] * 圧力[pa]  ≒  π * (シリンダ内径[mm] / 2)^2 * 駆動速度[mm/s]
例えばSYJ5000 C = 3.72 で内径φ80のシリンダーを動かす場合
3.72  * 500000 = 3.14 * 40 * 40 * 370
370mm/s程度動くことが分かる。これはSMCの個別カタログ値320mm/sより2割くらい大きい。
たぶん動作抵抗とかだと思う。
めんどくさいのでπ/4を削る。
3.72  * 500000 = 80 * 80 * 290
290mm/sと考えとけば少し余裕持って選定できる。

ベース配管型マニホールドブロックの一時側エア接続ポート
Pポート、Rポートはシリーズを決めた瞬間決まる。
音速コンダクタンスは2位置、弾性体シールのとき
SYはプラグリード(個別配線)VQはプラグインの例
CircleCIのOrbの自作

## イベントページ

下のイベントで行ったハンズオンの記録です。

[【オンライン】CircleCI コミュニティもくもく会 #13【今夜、Orbを作ってみよう】 (2022/04/07 18:30〜)](https://circleci.connpass.com/event/242590/)

## TL;DR

- Orb自作のハードルは低い。config.ymlさえ書ければすぐ作れる
- Orbにすることで可読性と再利用性が向上
- 組織内だけで共有する仕組みも提供している

## 対象

Circle CIをすでに使ったことがある人。

以下を前提とする。

- GitHub、CircleCIのアカウントを持っている
- GitHubとCircleCIの連携がすでに済んでいる
- `.circleci/config.yml` までは書いたことがある

## 環境設定

CircleCIのプロフィールページのサイドメニューでOrganization settings**移動する。

**Security＞Orb Security Settings** で未公認のorbを有効にする

![スクリーンショット_2022-04-07_19.40.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20439/d25124b0-5bde-9b5c-860c-d2cbae92779d.png)


CircleCI の CLI をインストールする
mac の場合は Homebrew。
それ以外の環境は[公式ドキュメント](https://circleci.com/docs/ja/2.0/local-cli/)を参照。

```bash
% brew install circleci
```

CircleCI の API キーを作成する。CircleCI のプロフィールページで作成し、コピーしておく。

CircleCI CLIの設定を行う。API　キーを聞かれるので、先ほどのキーを貼り付ける。

```bash
% circleci setup
```

namespaceを作成する

```bash
% circleci namespace create <name> github <name>
```

## サンプルプロジェクトの複製

下のGitHubレポジトリを fork し、ローカルに clone。

[https://github.com/mayoct/CCI-Hello-Orb](https://github.com/mayoct/CCI-Hello-Orb)

## Orb作成

orbを作成する

```bash
% circleci orb create <name>/hello
```

サンプルプロジェクトのフォルダに移動し、validate をかける

```bash
% circleci orb validate ./orb.yml 
Orb at `./orb.yml` is valid.
```

orbを公開する

```bash
% circleci orb publish ./orb.yml  <name>/hello@dev:alpha
```

バージョン番号（@以降）を数字にすると世界中からアクセスできるので注意。逆に dev だと開発中になり、90日経過すると自動で消える。

リストコマンドで確認

```bash
% circleci orb list <name> --uncertified
Orbs found: 1. Includes all certified and uncertified orbs.

<name>/hello (Not published)
```

### 動作テスト

.circle/config.yml の4行目を自分のものに書き換える

```yaml
version: 2.1

orbs:
  myorb: **<name>**/hello@dev:alpha

workflows:
  hello_places_workflow:
    jobs:
      - myorb/hello_tokyo
      - myorb/hello_osaka
      - hello_fukuoka

jobs:
  hello_fukuoka:
    executor: myorb/hello_executor
    steps:
      - checkout
      - myorb/hello_generic_cmd:
          placeName: "Fukuoka"
```

コミットしてGitHubにpush

### 動作確認

Circle CIの画面を開く。

Projects ページから先ほど作った Hello-CircleCI の連携を有効にする。

実行結果をみる
![スクリーンショット_2022-04-07_19.40.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20439/53bc570c-e85b-c935-102f-13f407ac3024.png)

![スクリーンショット_2022-04-07_19.27.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20439/5e9a8e93-9b0e-5f03-d959-185683f5f02b.png)

## まとめ

* 書き方の基本は *workflow のない config.yml*。
* パラメータを受け取るなどして再利用が可能。
* OrbからOrbも呼び出せる（スライドの今どきの「Orb プロジェクト構成」も参照）。組織のノウハウを作ってほしい

## 補足

create に `—private` オプションをつけると、組織（社内、個人）のみの間で使える
参考動画 [https://www.youtube.com/watch?v=r_lFUlLc3Ag](https://www.youtube.com/watch?v=r_lFUlLc3Ag)
    
カテゴリも登録できる。Orb一覧で絞り込みに使われる。
  [https://circleci.com/developer/ja/orbs](https://circleci.com/developer/ja/orbs)
調べても意外とでてこない「安心してgit pushする」方法


## はじめに
みなさん、安心してpushしていますか？
特に、force pushをする時の緊張度合いは半端じゃありませんよね。

今回は緊張を解消するべく、安心してgit pushする方法を紹介します。（簡単！）

## この記事の対象者
- 最近Gitを使い始めた初学者
    - コマンドの詳しい意味など、基本的なコマンドはこちらでは触れません
        - 参考：
            - [いまさらだけどGitを基本から分かりやすくまとめてみた](https://qiita.com/gold-kou/items/7f6a3b46e2781b0dd4a0)
            - [【Git】基本コマンド](https://qiita.com/konweb/items/621722f67fdd8f86a017)

## push方法

:warning: `[ ] は削除して適量変更してください　(例：　git commit -m "Fix typos")`

### commitしてpushする
```
git status //pushしたいファイルと中身を確認する

git add . //addの方法は適切に変えてください

git commit -m "[commit message]"

git status //pushしたいファイルが全てcommitできているか確認する

git diff origin/[pushしたいbranch名] //pushしたいbranchとの差分を確認する

git push origin [pushしたいbranch名]

```


### force pushする(rebaseが完了した体)
```

git log //commitが期待した状態かを確認する 

git diff origin/[pushしたいbranch名] //pushしたいbranchとの差分を確認する

git push origin [pushしたいbranch名] -f //最後に-fを付けると意図していないbranch名を指定した際に気が付ける可能性が増えます(多分)

```


## おわりに
いかがでしたか？
手順も多くないので、今日からでも始められると思います。
この手順であなたも安心したgit pushライフを！

もっとこうすれば良いなどありましたらぜひ教えてください:pray:
PHPの外部ファイルを読み込み

# 外部ファイルの読み込み
PHPでは違うファイルで書いたものを別のファイルで読み込んで出力させることができます。
その際にrequireとincludeを使います。


### requireとinclude
外部ファイル読み込み失敗したときにエラーで終了するか警告で継続するかの違いがそれぞれあります。

⚫︎```require```はエラー（Fatal）となり処理を停止します。
⚫︎```include```は警告（Warning）となり処理は継続します。

基本はrequireは処理が止まるのでこちらの方が良さそうです。


require_once();とinclude_once();というものがあり
これは1回のみ読み込むのに使います。



## requireを使う

ここでは```common.php```を作ります。
```php
$practice = "外部ファイルの読み込み練習";

function filePractice(){
    echo "外部ファイル読み込み関数";
}
```

別のファイル```sample.php```を作ります。
```php
equire 'common.php';  //読み込むファイル

echo $practice;

echo "<br>";

filePractice();

//外部ファイルの読み込み練習
//外部ファイル読み込み関数
```
となります。

もしcommon.phpがフォルダにある場合は
```php
require 'practice_file/common.php';  //読み込むファイル
         //practice_fileの中のcommon.php

echo $practice;

echo "<br>";

filePractice();
//外部ファイルの読み込み練習
//外部ファイル読み込み関数
```
階層が１つ上がる場合は

```php
require '../practice_file/common.php';
```
のように```../```を使います。

# _DIR__FILE マジック定数
これは***今いるファイルの絶対パスが表示***できます。

```php
require __DIR__ . '/practice_file/common.php';  //読み込むファイル

echo $practice;

//echo "<br>";

echo __FILE__;

filePractice();

//外部ファイルの読み込み練習/Applications/MAMP/htdocs/sample.php外部ファイル読み込み関数
```



# 参考資料
https://uxmilk.jp/15560
【初心者応援】新人エンジニアがPRのクオリティを上げる3つの方法

# はじめに
[新人プログラマ応援 - みんなで新人を育てよう！](https://qiita.com/official-events/3f21c92121aa125807b4)
ということで、今月から社会人となり、エンジニアになる方も多いのではないでしょうか？
今月は上記イベントに合わせて初心者応援をキーワードとして記事を書いていこうと思います。

今回は初心者応援記事第3弾、新人の方がPRのクオリティを上げる為の方法を3つご紹介したいと思います。

# その１：レビュー依頼前に差分を自己レビューする
まず1つ目は、自己レビューをしっかり行うという事です。
新人の方であれば、業務にも慣れなければならない状況で余裕もなく、確認が疎かになっていませんか？

これが原因で本来気がつく事ができた修正事項に気がつく事ができず、指摘につながるなんて事がよくあると思います。

余裕がない状況であればあるほど、急がば回れという言葉を思い出してみてください。
確認する時間は掛かりますが、指摘が減れば結果回収できる時間も多いはずです。

最初のうちはご自身の差分を３度見するくらいが丁度良いと思います。
指摘が減る事で心の余裕にも繋がるはずなので、是非レビュー依頼前に自己レビューをきっちり行う事をお勧めします。

# その2：過去のPRをサッと確認する
2つ目ですが、過去のPRを確認するというものです。
これは同じ指摘を何度も貰わないようにする為の方法です。

細かい同様の指摘を何度ももらってしまうなんて事が新人の方ではありがちです。

最初のうちは指摘の数も多く、もらった指摘を全部覚えるのも大変ですよね。
そんな時は、レビュー依頼する前にサッと過去のPRを眺めてみると良いと思います。
合わせて同期の方のPRを見る事ができるようでしたら、それも良いと思います。

過去に受けた指摘をレビュー前のPRにも生かせるポイントがきっと見つかるはずです。
こうして同じ指摘をもらわないように意識していると、だんだん指摘の数は減っていくと思います。

指摘の数がなかなか減らない方は、是非過去のPRを参照してみてください。

# その3：PRに補足コメントを残す

３つ目はPRに補足コメントを残すというものです。
これは不必要なコミュニケーションを減らし、PRのクオリティ向上に繋がります。

例えば、他の方のコードを見た時に現状に至った経緯を知る必要がある場面があると思います。
これをご自身のPRで考えてみてください。
仕様を知らない方がレビューをするとしたら、そのコードが正しいかどうかというのは、仕様によりますよね。
そうなると、そこでコミュニケーションが必要になりますが、予め情報を提示しておけばこのコミュニケーションは不要になります。
必要なコミュニケーションのみに注力出来ると、レビュワーも不要なコメントをする必要がなくなり、レビューのクオリティが上がります。

また、ご自身のコードを客観視出来るようになると、不具合や指摘につながるコードを見つけやすくなるという副産的なメリットもあります。

その1で自己レビューに関して挙げていますが、是非一度合わせてご自身のPRを客観的に見ていただく事をお勧めします。

# さいごに
新人の方は提出するPRがなかなか通らず、悩む場面多いですよね。
コメントはコミュニケーションの一環ですが、数が多ければ多いほどご自身が虐げられているような気持ちになる方もいるかなと思います。
そんな時に少しでもPRのクオリティを上げる事ができれば、ご自身のメンタルを守る事にも繋がるはずです。
是非PRで悩んでいる方は上記３つの事項を実践していただければと思います。
久しぶりにGNS3（その10：セキュアL2トンネリング/ブリッジ）

# IPsecを伴ったL2トンネリング/ブリッジ
（いつの間にか本シリーズも第10回に突入）
[その９](https://qiita.com/infinite1oop/items/14ab43877d5d417df1aa)の続編。IPsecを用いてトンネリング部分を暗号化する。

## トポロジー
![Topology(IPSec).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/86df9a70-dd8f-7485-dc0b-924bd7e2beb4.png)

同一セグメント（10.0.0.0/24）のトンネリング区間（R2-R3）をIPsec化する。末端のPCには固定IPアドレスをアサインする。

## 設定
PC1およびPC2は自明のため省略。

### R2
L2トンネリングについては、[その９](https://qiita.com/infinite1oop/items/14ab43877d5d417df1aa)の説明参照。

```
pseudowire-class test
 encapsulation l2tpv3
 ip local interface FastEthernet0/0

interface FastEthernet0/1
 no ip address
 xconnect 192.168.2.2 1 encapsulation l2tpv3 manual pw-class test
  l2tp id 1 2

ip route 0.0.0.0 0.0.0.0 FastEthernet0/0
```

IKEおよびIPSecの詳細については、[「その４：トンネリング：IPsec」](https://qiita.com/infinite1oop/items/c130efb34d111326e44e)の説明を参照。IKEおよびIPsecの接続先として、対向ルーターであるR3のIPアドレスを指定する。

```
crypto isakmp policy 1
 encr aes
 authentication pre-share
 group 2
crypto isakmp key testpwd address 192.168.2.2
crypto isakmp keepalive 60 periodic

crypto ipsec transform-set ABC esp-aes esp-sha-hmac 
 mode transport
```

IKEおよびIPsecを適用するマップの設定。暗号化の対象をプロトコル番号「115」（L2TP）としている。プロトコル番号については、[プロトコル番号 ( IP Protocol Number )](https://www.infraexpert.com/study/tea11.htm)を参照。

```
crypto map To_R3 1 ipsec-isakmp 
 set peer 192.168.2.2
 set transform-set ABC 
 match address DEF

ip access-list extended DEF
 permit 115 any any
```

接続先となる物理I/Fに上述したマップを適用する。

```
interface FastEthernet0/0
 ip address 192.168.1.2 255.255.255.0
 crypto map To_R3
```

### R3
R2とほぼ同じのため、説明省略。

```
pseudowire-class test
 encapsulation l2tpv3
 ip local interface FastEthernet0/0

crypto isakmp policy 1
 encr aes
 authentication pre-share
 group 2
crypto isakmp key testpwd address 192.168.1.2
crypto isakmp keepalive 60 periodic

crypto ipsec transform-set ABC esp-aes esp-sha-hmac 
 mode transport

crypto map To_R2 1 ipsec-isakmp 
 set peer 192.168.1.2
 set transform-set ABC 
 match address DEF

interface FastEthernet0/0
 ip address 192.168.2.2 255.255.255.0
 crypto map To_R2

interface FastEthernet0/1
 no ip address
 xconnect 192.168.1.2 1 encapsulation l2tpv3 manual pw-class test
  l2tp id 2 1

ip route 0.0.0.0 0.0.0.0 FastEthernet0/0

ip access-list extended DEF
 permit 115 any any
```

### R1
自明。

```
interface FastEthernet0/0
 ip address 192.168.1.1 255.255.255.0

interface FastEthernet0/1
 ip address 192.168.2.1 255.255.255.0
```

## 検証
### PC1からPC2へのping
PC1-R2のWiresharkデータ。ARPおよびICMP（ping）。当然ながら暗号化されていない。
![PC1-R2のコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/9faffaea-f031-481c-07f3-4484481f45b5.png)

R2-R1のWiresharkデータ。暗号化されている。
![R2-R1のコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/5ee458fa-e09c-a44e-e504-bdbc2cbe4731.png)

## その他の参考サイト
- [CISCOとSoftetherでL2TPv3 over IPSec](https://www.neko6.info/archives/2031)
- [L2TPv3 over IPSecVPN を用いた LAN-to-LAN 接続設定例](https://www.cisco.com/c/ja_jp/support/docs/security-vpn/ipsec-negotiation-ike-protocols/l2tpv3-overipsec.html)
pillow(PIL)でメモリイメージを扱う

# メモリ上で画像を弄りたくなる時もたまにある。
そう、たまにあるんです。
大体は速くなるからね、やりたくなるよね。

なので簡単に使えるように作ってみた。

```python:arrayimage.py
from PIL import Image, ImageTk

class ArrayImage:
    def __init__(self, size=(10, 10)):
        self.sizeW = int(size[0])
        self.sizeH = int(size[1])
        self.size = (self.sizeW, self.sizeH)
        self.byteData = bytearray(self.sizeW * self.sizeH * 3)
       
    def image(self):
        return ImageTk.PhotoImage(Image.frombytes("RGB", self.size, bytes(self.byteData)))

    def index(self, pos):
        return (pos[1] * self.sizeW + pos[0]) * 3

    def set(self, pos, rgb):
        index = self.index(pos)
        self.byteData[index:index+3] = rgb

    def get(self, pos):
        index = self.index(pos)
        return tuple(self.byteData[index:index+3])
```

使うにはこう。

```python
import tkinter as tk
import random

from arrayimage import *

class MyApp:
    def __init__(self, cnf={}, **kw):
        self.root = root = tk.Tk()
        self.ai = ArrayImage(size=(128, 128))
        self.canvas = c0 = tk.Canvas(root, width=self.ai.sizeW*3, height=self.ai.sizeH*3)
        c0.pack()

    def mainloop(self):
        self.root.after(100, self.dispImage)
        self.root.mainloop()

    def dispImage(self, e=None):
        for y in range(self.ai.sizeH):
            for x in range(self.ai.sizeW):
                self.ai.set((x, y),
                            (random.randint(0,255),
                             random.randint(0,255),
                             random.randint(0,255))
                       )
        self.dispimg = self.ai.image()
        self.dst = self.dispimg._PhotoImage__photo.zoom(3)
        self.canvas.create_image(0, 0, anchor="nw", image=self.dst)
        self.root.after(33, self.dispImage) # 1 / 30 * 1000


if __name__ == "__main__":
    app = MyApp()
    app.mainloop()
```

## 動作イメージ
こんなかんじで砂嵐が表示されます。

![sandstorm](https://user-images.githubusercontent.com/12671694/162176674-a394bf6d-5790-4124-8a9f-176b70abdb69.png)

それなりに速く動くけどCPU利用率はなかなか。
あとは大きな画像を作るとそれなりにヘヴィーです。
使いどころが難しそうだけどpico8的なものを作ったりするときにひょっとしたら役にたつかもしれないですね。
整数数学A「2022年一橋大学前期第1問」2^a*3^b+2^c*3^d=2022を,エクセルvbaとsympyで


# 問題

```
 0 以上の整数 a ， b ， c ， d の組
2^a*3^b+2^c*3^d=2022
2**a+3**b+2**c+3**d=2022
```

https://nyushi.sankei.com/honshi/22/ht1-21p.pdf


大学入試数学問題集成＞

https://mathexamtest.web.fc2.com/2022/202210272/2022102720100.html


# 解答

一橋の問題は素直であるが、誘導も少なく、難易度は高い。 ＜ 河合塾分析より
難易度標準で解答2頁でした。

https://kaisoku.kawai-juku.ac.jp/nyushi/honshi/22/ht1-21a.pdf

https://kaisoku.kawai-juku.ac.jp/nyushi/honshi/22/ht1.html


整数問題の基本事項...地道な作業が必要なところもあります。 ＜　わか様より


https://waka-blog.com/?p=4285T





# エクセルvbaで

あっという間に結果がでました。エクセルすごいですね。
素数も考えなくて、いいですね。(20220425)


```vb
'nMax = 2022
'実行時エラー '6':
'オーバーフローしました｡
Sub aaa_main()
nMax = Int(Log(2022) / Log(2)) + 1
ActiveSheet.Cells.Clear
MsgBox "実行を開始します"
iR = 0
For i = 0 To nMax
For j = 0 To nMax
For k = 0 To nMax
For l = 0 To nMax
    If 2 ^ i * 3 ^ j + 2 ^ k * 3 ^ l = 2022 Then
       iR = iR + 1
       Cells(iR, 1) = i
       Cells(iR, 2) = j
       Cells(iR, 3) = k
       Cells(iR, 4) = l
    End If
Next
Next
Next
Next
End Sub
'1	5	9	1
'9	1	1	5
```

# SymPy Liveで(Pycharmでも)

以下サイトに、ソースコードを貼り付けて、Evaluateです。

https://live.sympy.org/

```python
from sympy import *
# nMax=2022 恐ろしくて、途中であきらめました。どなたか時間を計ってみてください。
nMax=int(log(2022)/log(2))+1
for i in range(nMax):
    for j in range(nMax):
        for k in range(nMax):
            for l in range(nMax):
                 if 2**i*3**j+2**k*3**l==2022:
                    print("#",i,j,k,l)
# 1 5 9 1
# 9 1 1 5
```

https://note.nkmk.me/python-int-max-value/






# ついでに(失礼な!!) wolframalphaも

興味のある方は、どうぞ。
何かあるのでしょうね。奥が深そうです。解説してもらうと助かります。

https://www.wolframalpha.com/input?i=2%5Ea*3%5Eb%2B2%5Ec*3%5Ed%3D2022&lang=ja


# 感想

先に解答の一番下を見て、出力とあっていたのでほっとしました。
やってて、ワンパターン化してきました。
excelのある時代に、整数解の問題はたいへんですね。何とかならないものですか？
選抜試験ですから。
[MySQL] 既存カラムのデフォルト値をNULLに変更する

あるカラムのデフォルト値をNULLに変更したい。
```前提：
既存テーブル名　　　： sample_table
既存カラム名　　　　　　　： hoge_column
フィールドの型　　　 ： varchar(10)
フィールドの属性 ： DEFAULT NULL
```
ALTER TABLE **sample_table** MODIFY COLUMN **hoge_column varchar(10) DEFAULT NULL**;

今回は sample_table の hoge_column に、可変長文字列10文字の型かつデフォルト値NULLを設定した。

参考：
すでに作成してあるカラムにNULLを格納できないようにする
https://26gram.com/mysql-not-null
```
ALTER TABLE テーブル名 MODIFY COLUMN カラム名 データ型 NOT NULL;
```
ACM、オライリー本サブスク止めるってよ

4/6(水)の夜中、衝撃のメールがACMから届きました😱


(メールから本文抜粋＆DeepL翻訳)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406339/da3d53d7-6c3e-90d8-1e87-747a91efc5d5.png)

# そもそもACM特典って何？
こちらの記事を参照ください。（あと2ヶ月で終了しますが）すごい特典です

https://qiita.com/mossan_hoshi/items/7a044036552b7a8687ca

# 対策

## 方法
オライリー公式のサブスク「O'reilly Learning」に契約を切り替える。
- 4/7現在、私はまだ契約をACMから移行していませんが、ACMアカウントからデータなどは引き継げそうです（ログイン後のメニューに「O'reilly Learning」への契約menuがあります）

https://www.oreilly.com/online-learning/individuals.html

### 費用

https://www.oreilly.com/online-learning/pricing.html

- 月払い： ＄49 / 月 ( ＄588 / 年 )
- 年払い： ＄499 / 年
    - これまで（ACM会員費＄99 / 年）の約5倍ですが、そもそもこれまでが異常にお得過ぎたという事だと思います。サービスを継続してもらうためにも、いいコンテンツにはちゃんと対価を払いたいところです

(4/8更新)オライリーから通知があり現ACM会員は **初年度は＄100引きの＄399** とのことです
![Screenshot_20220408-232610.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406339/670b7d4b-a55f-f695-d834-a3d8dacbe0e7.png)



# さいごに
このサブスクを始めてまだ半年ですが、オライリー本サブスクはもう私の生活と切っても切れない関係になっています。
普通に読んだりもしますが、 **何かをしている時に「ながら作業」としてTTSで聞き流す** という使い方が個人的には非常に気に入っています🔊👂
（英語は苦手なのでブラウザのGoogle翻訳機能で日本語の翻訳したものを読み上げさせています）。

気になる技術トピック・キーワードが出てきたときにサクッと検索してそのジャンルで一番人気の本を読み始められるという体験は、学習を始める敷居を下げ、技術の幅を大きく広げるきっかけになります(さらに、買い取った本ではないので途中で読むのを止めてもそこまで心は痛みません💖）
非常におススメのサービスです。


ACM、素晴らしい機会をありがとう👋
オライリー、これからもよろしく🤗
DOM、Node、Elementを理解する

# 概要
JavaScriptで動的にHTMLを操作することが増え、より深く仕組みを知ってみたいと思い、理解した内容を記載する。
<b>※結論、タイトルとは逆の順で理解した方がわかりやすかったので、その流れで記載する。</b>

# Element(要素)
* Element(要素)とは、`<p>要素の内容</p>`のように`「タグ」+「内容」`の組み合わせのこと。
* 各要素は、共通したインターフェースを継承し、さらに細分化したインターフェースを実装している。
* また、これらは`文書を構成する要素(Object)`と考えることもできる。

> ここでいう**インターフェース**とは
> プロパティ(情報)、メソッド(処理のまとまり)などを定義しているもの。
> 継承すると継承元で定義されているプロパティや、メソッドなどを参照・実行できる。
> また、これらは`DOMインターフェース`と呼ばれる。

## 例：pタグ、imgタグが継承しているインターフェース
「pタグにはsrc属性が指定できないが、imgタグではsrc属性が指定できる」という事象をもとに考えてみる。

* pタグは「`HTMLParagraphElement`」というインターフェースを実装している。
* imgタグは「`HTMLImageElement`」というインターフェースを実装している。
* また、各インターフェースはそれぞれ「`HTMLElement`」というインターフェースを共通して継承している。

これは、imgタグが実装している「`HTMLImageElement`」には「src」というプロパティが定義されているが、
pタグが実装してる「`HTMLParagraphElement`」には定義されていないからである。

普段、何気なく「このタグのこの属性を指定」と行っている裏側ではこのような実態があるようだ。

> **インターフェース「HTMLElement」** について
>「HTMLElement」もまた別のインターフェースを継承している。
> すなわち、`pタグ、imgタグの要素`も直接的ではないが、継承している(継承元のプロパティやメソッドを参照・実行可能)ということになる。

> **参考：HTML Standard**
> [4.4.1 The p element](https://html.spec.whatwg.org/multipage/grouping-content.html#the-p-element)
>[4.8.3 The img element](https://html.spec.whatwg.org/multipage/embedded-content.html#the-img-element)

# Node
* DOMでは、前項のHTMLタグで生成した各Element(要素)やコメントなど、文書の構成要素(Object)一つ一つを「`Node`」と呼ぶ。
* Nodeには12種類定義されており、HTMLタグで生成した要素は「`ELEMENT_NODE`」に分類される。
* `Nodeインターフェース`というのもあり、前項で登場した「HTMLElement」も元をたどれば継承している。
* また、Nodeはネスト(divタグの中にpタグが入ったり)が可能で、木のような階層構造で表現できる(`DOMツリー`と呼ばれる)

## Nodeの種類
普段何気なく触れているところでいうと
* `ELEMENT_NODE`(HTMLで使用するタグ = bodyタグ、pタグ、divタグ...)
* `DOCUMENT_TYPE_NODE`(HTMLファイルの先頭に記載している「`<!DOCTYPE html>`」)
* `COMMENT_NODE`(HTMLファイルに記載したコメント)

など...

## Nodeの種類(nodeType)を調べる方法(GoogleChromeの場合)
①ブラウザの検証ツールを開き、「Elements」タブから対象の要素を選択(この例ではbuttonタグの要素がグレーに反転している)
②「Properties」タブを開く。
③「nodeType」と入力し、フィルターをかけ、今回だと「nodeType: 1」というのがどの分類かを調べるキーワードになる。
④『[MDN](https://developer.mozilla.org/ja/docs/Web/API/Node/nodeType)』などで記載しているnodeTypeの表を見ると「1」は「`ELEMENT_NODE`」となっていることが分かる。
※HTMLのコメント箇所で試してみると「COMMENT_NODE(nodeType: 8)」と分類されていることが分かるはず。
![スクリーンショット.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/640274/a7c8262a-8838-1a58-7d61-bf9372a13dae.png)

# DOM(Document Object Model)
* ブラウザAPIの一種であり、文書(`HTML`や`XML`)を`JavaScriptなどのスクリプトで操作するための仕様・窓口`(ブラウザで実装されている)
* この仕様を実現するために、前述の`Element`や`Node`が存在する。

>DOMの仕様は、Web技術の標準化を行っている「`W3C`」や「`WHATWG`」という団体が共同で仕様の策定等を行っている。

# 考察
DOMとは、
* **Document(文書)** を**Object(各Node)** で構成し、また、それらを木のような階層構造を模倣・表現し(**Model** 化)操作可能にする仕様で、
* 「`ある要素をJavaScriptで動的に変化させる`」とは、その文書を表現している`DOMツリー`から対象の`Nodeが持つプロパティ`を変更するということ。
* 「`ある要素をJavaScriptで動的に追加する`」とは、`DOMツリー`の指定した場所に`Node`を追加し、文書に変更を加えるということ。
(...考えれば今まで何気なくやっていたことの理解がもっと深まりそう)

という考察に至った。

# あとがき
ここまで自分なりに解釈・落とし込んだ内容を記述してきた。

特に、`DOMインターフェース`を理解すると、`JavaScriptでの操作`や`CSSでのスタイル設定`など、より理解が進むと思われる。

標準化団体が掲示しているドキュメントなど、読み届いていない部分もあるため、これからより知識を深めていきたい。