OmniAICreator/Qiita-1.07M huggingface dataset:
Docker環境確認

### docker system infoコマンド実行例

```
$ sudo docker system info
Client:
 Context:    default
 Debug Mode: false

Server:
 Containers: 0　　←コンテナの数
  Running: 0
  Paused: 0
  Stopped: 0
 Images: 0
 Server Version: 20.10.14　　←dockerのバージョン
 Storage Driver: overlay2　　←ストレージドライバーの種類
  Backing Filesystem: extfs
  Supports d_type: true
  Native Overlay Diff: true
  userxattr: false
 Logging Driver: json-file
 Cgroup Driver: systemd
 Cgroup Version: 2
 Plugins:
  Volume: local
  Network: bridge host ipvlan macvlan null overlay
  Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
 Swarm: inactive
 Runtimes: io.containerd.runc.v2 io.containerd.runtime.v1.linux runc
 Default Runtime: runc
 Init Binary: docker-init
 containerd version: 3df54a852345ae12XXXXXXXXXXXX
 runc version: 
 init version: de40ad0
 Security Options:
  apparmor
  seccomp
   Profile: default
  cgroupns
 Kernel Version: 5.15.0-40-generic
 Operating System: Ubuntu Core 18
 OSType: linux　　　←OSの種類
 Architecture: x86_64　　←アーキテクチャ
 CPUs: 4
 Total Memory: 15.55GiB
 Name: XXXXXXXX
 ID: XXXXXXXX
 Docker Root Dir: /var/snap/docker/common/var-lib-docker
 Debug Mode: false
 Registry: https://index.docker.io/v1/
 Labels:
 Experimental: false
 Insecure Registries:
  127.0.0.0/8
 Live Restore Enabled: false
```

### docker system df (docker system df -v) コマンド実行例
```
$ sudo docker system df
TYPE            TOTAL     ACTIVE    SIZE      RECLAIMABLE
Images          1         1         231.3MB   0B (0%)
Containers      4         1         272B      11B (4%)
Local Volumes   0         0         0B        0B
Build Cache     0         0         0B        0B

#詳細表示オプション-v付与
$ sudo docker system df -v
Images space usage:

REPOSITORY   TAG       IMAGE ID       CREATED         SIZE      SHARED SIZE   UNIQUE SIZE   CONTAINERS
centos       latest    5d0da3dc9764   10 months ago   231.3MB   0B            231.3MB       4

Containers space usage:

CONTAINER ID   IMAGE     COMMAND                 LOCAL VOLUMES   SIZE      CREATED        STATUS                      NAMES
11bbc82b2fca   centos    "/bin/ping localhost"   0               11B       25 hours ago   Exited (137) 13 hours ago   sleepy_beaver
1917c7f76a5f   centos    "/bin/bash"             0               261B      35 hours ago   Up 29 seconds               test2
35cb1215e744   centos    "/bin/cal"              0               0B        35 hours ago   Exited (0) 14 hours ago     test1
99671ed077ff   centos    "/bin/bash"             0               0B        35 hours ago   Exited (0) 13 hours ago     sad_wescoff

Local Volumes space usage:

VOLUME NAME   LINKS     SIZE

Build cache usage: 0B

CACHE ID   CACHE TYPE   SIZE      CREATED   LAST USED   USAGE     SHARED
```
Zabbixの設定

## ブラウザ上でのZabbixの設定
Zabbixの設定を行った際に苦労したので簡単にまとめてみました。

＊DNS名やIPアドレスは以前使っていたもので現在は使用していません :)

### ホストの追加
ホスト作成を選択
IPアドレス：プライベートIP
DNS名：設定したDNS名
ポート番号：10500

![スクリーンショット 2022-07-16 15.59.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2723997/b30c129e-fe25-50a7-be1b-41856c4622c4.png)

※ vi /etc/resplv.confのnameserevrがDNSのプライベートIPになってることを確認 

### メール設定

管理の中のメディアタイプを選択しEmailの編集

※zabbixが直接外部と接続できる時（NATgatewayなどを使用した場合）はアドレスを使用し、それ以外の場合はIPアドレスを使用

![スクリーンショット 2022-07-16 16.02.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2723997/24beaf69-3b75-ca57-0519-323b0dfdae1a.png)


SMTPサーバー　
ns1.nasu.rplearn.net or プライベートip

SMTP helo         
nasu.rplearn.net or プライベートip

送信元メールアドレス
自分で設定したメールアドレス
今回は（zabbix@nasu.rplearn.net）


### アクション設定

※障害が起きた際に上記で設置したメールアドレスにメールが届く
名前：障害発生をメールで通知

![スクリーンショット 2022-07-16 16.04.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2723997/fc9566f6-8ded-057e-542a-bafe8bf7c3a9.png)

実行条件の変更を選択
ユーザー：Admin
※今回は送信したいユーザーにadminを選択した為、nasu-zabbix@nasu.rplearn.netに送信される


![スクリーンショット 2022-07-16 16.05.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2723997/c22b44c1-1e48-ca54-ffaa-e717d8ecb0e3.png)

### まとめ

今回はホストの追加とメール設定をまとめてみました。
今後アイテムやトリガーの設定を乗せていきたいと思います。
Linux初期設定

:::note info
Linux初期設定の便利メモ
:::


### vi初期設定
:::note info
homeディレクトリのユーザフォルダ配下にvi用の設定ファイルを作成する。
:::
これで、日本語キーボードでもBackSpaceキーなどなどまともに使えるようになる
ついでに行の表示やインデントの調整も入れておく。

```bash
YYY@XXX:~$ cat /home/YYY/.vimrc
set backspace=indent,eol,start
set nocompatible
set number
set autoindent
set tabstop=4
set shiftwidth=4
```

### start up 起動用シェルの中身
以下のファイルをデスクトップ等に配置しておくと、イチイチコマンドを実行させる手間がなくて便利
```bash
sh .bash_profile
echo 'passwod' | sudo -S chmod 777 /var/run/docker.sock
```
忘却録 Excelでブックを開かずに高速で値を取得する

Excel4Macroを使用してブックを開かずに中身を取得します。
開いて確認する場合より最大で1桁程度早くデータを取得できますが、複数のセルを確認する場合は素直に開いてください。

以下のモジュールをどこかしらに置いてください。
```vb
Public Function GetInBookValue(filePath$, sheetName$, r1C1Str$)

    Dim reverseName$: reverseName = StrReverse(filePath)
    Dim fileNameLenth&: fileNameLenth = InStr(reverseName, "\") - 1
    Dim folderPath$: folderPath = Left(filePath, Len(filePath) - fileNameLenth)
    Dim fileName$: fileName = StrReverse(Left(reverseName, fileNameLenth))
    
    Dim arg$: arg = "'" & folderPath & "[" & fileName & "]" & sheetName & "'!" & r1C1Str
    
    On Error Resume Next
            '関数失敗時はemptyが返されます。
            GetInBookValue = ExecuteExcel4Macro(arg)
    On Error GoTo 0

End Function

```  

使用例
```vb
Sub sample()
    debug.print GetInBookValue("C:\hoge.xlsx", "Sheet1", "R1C1")
End Sub

```  

セルの指定はR1C1方式でないと対応していません(たぶん)

当方は工場でのデータ管理をしているのですが、特定フォーマットで所定の場所に保管されているファイルを条件分岐で処理する場合などにまあまあ便利に使えてます。

そういう場合過去に書いたこういう所定のフォルダ以下のファイル(サブフォルダ有/無)リストを返す関数を作っておくと便利です。
https://qiita.com/es2/items/eeb3a02891ff50b6dabc
gitにコミットしたらJenkinsのジョブが起動するようにする

# やりたいこと

gitにコミットしたらJenkinsのジョブが起動するようにしたい。


# 手順


### 諸々コンテナを準備

https://qiita.com/ryot0/items/0990489fd0d27f43667a


### JenkinsでAPIトークンを発行

ユーザアイコン　→　設定　→　APIトークン


### Jenkinsでリモートトリガーを設定

ジョブ　→　設定　→　リモートトリガー　→　認証トークン


### gitリポジトリのupdateフックを設定

```shell:xxx.git/hook/update
#!/bin/sh

refname="$1"
oldrev="$2"
newrev="$3"

case "$refname" in
	refs/heads/master)
                curl -X POST --user "認証ID:APIトークン" http://picobuildcont01:8080/job/pico-playground-master/build?TOKEN=認証トークン
                echo "Invoke jenkins job completed: pico-playground-master"
		;;
	*)
		echo "No commit action"
		exit 0 
		;;
esac

exit 0
```
ShellScriptでバックアップを作成

# Zabbixのデータベースをバックアップする方法（shellscript）
ShellScriptが苦手で日々勉強中です。
他の書き方もあるので是非シェアしていただきたいです。



## ShellScriptの書き方（Zabbixの場合）
```Bash
#!/bin/bash

DATE=`date "+%Y%m%d"`
BAKDIR=/mariadb_backup


# バックアップするDBの情報
DB_USER=zabbixuser
DB_PASS=zabbixpass
DB_NAME=zabbix

# mysqldumpコマンドでDBをバックアップ
mysqldump -u ${DB_USER} -p${DB_PASS} ${DB_NAME} > ${BAKDIR}/${DB_NAME}_${DATE}.bak

# パーミッションの設定
chmod 755 ${BAKDIR}/${DB_NAME}_${DATE}.bak

# バックアップ日のログを保存する
l="${BAKDIR}/db.log" ←ご助言をいただき変更しました。
echo backup as ${BAKDIR}/${DB_NAME}_${DATE}.bak at ${DATE}>>$l

# ７日より古いファイルを削除
find ${BAKDIR} -type f -name "${DB_NAME}_*.bak" -mtime +7 -exec rm -f {} \;

# 30日より古いlogファイルを削除
find ${BAKDIR} -type f -name “backup as ${BAKDIR}/${DB_NAME}_${DATE}.bak at ${DATE}” -mtime +30 -exec rm -f {} \;
```


## 時間を決めて実行する方法
crontabコマンドを使用します。

```php:crontab -e の設定 ３amに設定
0 3 * * * sh /home/zabbix_bak.sh  > /dev/null 2>&1
```
Ubuntuのキーボード設定（全角半角キー有効）

## Ubuntuで全角半角キーが機能しない件の解決方法
:::note info
ubuntuのキーボードで半角/全角キーが利用できなかった際の解決方法のメモ
:::

### 日本語のキーボードに変更
*キーボードレイアウトを表示した際に全角半角ではなく「'」になってしまっている場合*
```
$ setxkbmap jp

#上記だけでは、一時的な設定になってしまうため、.bash_profileファイルに記載しておく
$ touch ~/.bash_profile
$ echo "setxkbmap jp" >> ~/.bash_profile    ← ログイン時にコマンド実行(.bash_profile)
※ $ echo "setxkbmap jp" >> ~/.bashrc    ← ターミナル読み出し時にコマンド実行(.bashrc)
```
:::note warn
上記ではじめのうちは有効になっていたが、なぜか次第に有効にならず、ログインのたびに
$ sh .bash_profile を実行する羽目に…
→アプリケーションから検索で「自動」を入力して「自動起動するアプリケーションの設定」を開く
　→追加ボタンで作成したスタートアップ設定用のシェル(ファイル中身：setxkbmap jp)を登録して完了
:::

### キーボードショートカットの設定
1. Mozcのプロパティ画面を表示
　*ツール→プロパティ→一般タブ→キー設定*
2. キー設定の選択で編集
　*キー設定→編集*
3. 左から文字入力なしとなっている項目のHankaku/ZenkakuキーをIMEを有効化にする。
　*これで半角/全角キーを押すと日本語がオンになる。何度押してもオンになるだけ。オフにはならない。*
4. 次に文字入力なしとなっている項目のMuhenkanキーをIMEを無効化にする。
　*これで無変換を押せば英数字直接入力になる。何度押しても英数字になるだけ。*
:::note info
お好みの設定があるのであれば別のキーでも全然問題ない。
:::

***

#### 参考URL
[Ubuntu(Linux)のキーボード設定を日本語に変えて「半角/全角」でひらがなに「無変換」で英数字に変える方法](https://www.ultra-noob.com/blog/2020/117/ "謎技研")

***
Flutter バイブレーション機能

![スクリーンショット 2022-07-12 9.23.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1134006/38a59569-bec4-b64d-062f-99d273379274.png)
最新バージョンは下記より取得して下さい。
[vibration pub.dev](https://pub.dev/packages/vibration)
```
dependencies:
  vibration: ^layest
```

```dart
// ignore: import_of_legacy_library_into_null_safe
import 'package:vibration/vibration.dart';

// 振動させる
Vibration.vibrate();
// 振動機能があるか確認する
if (await Vibration.hasVibrator()) {
    Vibration.vibrate();
}
// １秒間振動させる
Vibration.vibrate(duration: 1000);
// 振動を止める
Vibration.cancel();
```
![スクリーンショット 2022-07-12 9.21.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1134006/037d57b9-86de-3895-97d6-2df53c920cc2.png)
基本的にはこちらの方が`Null Safety`に対応しているのでオススメです。
[flutter_vibrate pub.dev](https://pub.dev/packages/flutter_vibrate)
```
dependencies:
  flutter_vibrate: ^layest
```

```dart
import 'package:flutter_vibrate/flutter_vibrate.dart';

// 500ミリ秒振動させる
Vibrate.vibrate();
// 振動機能があるか確認しあれば振動させる
if (await Vibrate.canVibrate()) {
    Vibrate.vibrate();
}
// 500ミリ秒停止させる
final Iterable<Duration> pauses = [const Duration(milliseconds: 500)];
Vibrate.vibrateWithPauses(pauses);
```
踏み台サーバを経由してGitLabをホストした

踏み台サーバを経由した時のGitLabの設定が想定よりハマりました。その時の設定方法のメモ書きです。  
`ssl`とか`ssh`については今回は設定していません。

## 構成

今回の構成です。

![[Laptop PC] -> 8888[踏み台] -> 8080[GitLab Server 80[GitLab Docker]]](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166754/7c5fa6ec-cc9a-3182-dc0e-455504001a46.png)

- GitLabはリモートサーバ上でDockerを使って起動します。
- リモートサーバは`8080`ポートをDockerコンテナの`80`番にフォワードします。
- 踏み台サーバは`8888`番で受けたリクエストをリモートサーバの`8080`番にSSHでトンネリングします。

## 手順

### 1. リモートサーバでのGitLabの起動

今回はGitLabのDocker Imageを使用しました。

まずは`docker-compose.yaml`の作成です。

```yaml:docker-compose.yaml
version: '3.9'

services:
    image: gitlab/gitlab-ee:15.1.2-ee.0
    ports:
      - 8080:80
    environment:
      GITLAB_OMNIBUS_CONFIG: |
        external_url 'http://ip.address.of.jump:8888'
        nginx['listen_port'] = 80
    volumes:
      - ./config:/etc/gitlab
      - ./logs:/var/log/gitlab
      - ./data:/var/opt/gitlab
    restart: always
```

- リモートサーバの`8080`ポートをDockerコンテナの`80`番に割り当てます。
- `external_url`はGitLabのUIに表示されるURLです。 　
  踏み台サーバを経由してアクセスするため、踏み台サーバのIPアドレス`ip.address.of.jump`とポート`8888`を使用します。
- `nginx['listen_port']`は`80`番を使用します。　
  デフォルトではNGINXのポートは`external_url`の値で決まるため、`external_url`とNGINXのポートが異なるときは`nginx['listen_port']`を指定する必要があります (参考: <https://docs.gitlab.com/omnibus/settings/nginx.html#setting-the-nginx-listen-port>)。

下記コマンドで起動します。

```sh user@remote$ docker compose up -d ```

GitLabの準備は完了です。

### 2. 踏み台サーバでのポートフォワード

続いて`ssh`コマンドを用いてポートフォワードを行います。  

とりあえず踏み台サーバで鍵ペアを作成してリモートサーバに配置しましょう。  
詳しくは省略しますが、踏み台サーバ上で`ssh-keygen`で鍵を作成し、公開鍵`some_key.pub`の値をリモートサーバの`.ssh/authorized_key`に書き込みましょう。

下記コマンドでポートフォワードを行いました。

```sh
nohup ssh -N -p 22 someuser@ip.address.of.remote -L 8888:localhost:8080 -g &
```

- `nohup ... &`バックグラウンドでコマンドを実行するためのコマンドです。
- `-N`はリモートコマンドを実行しないためのオプションです。  
  `ssh -N -p 22 someuser@ip.address.of.remote -L 8888:localhost:8080 -g`を実行するとオプションの意味がわかるでしょう。
- `-L`はローカルフォワードのオプションです。　 
  ローカル(踏み台)の`8888`ポートをリモート(`ip.address.of.remote`) の`8080`ポートにフォワードしています。  
  この時、`-L 8888:localhost:8080`の`localhost`はssh先、つまりリモートサーバ上での`localhost`を指すようです ([参考](https://qiita.com/mechamogera/items/b1bb9130273deb9426f5)) 。  
- `-g`オプションをつけないと、踏み台サーバからのアクセスしかフォワードされません。

### 3. ブラウザからアクセス

ブラウザに `http://ip.address.of.jump:8888`を打ち込んでアクセスしてください。  
`502`が表示されるときはもう少し待ちましょう。

テキトーなリポジトリのクローン先のURLを確認しましょう。
踏み台サーバのアドレスになっていればOKです。

TANUKIアイコンが少したぬきらしくなりましたね。

## おわり

以上、踏み台サーバを経由してGitLabをホストする方法でした。
本番環境における500サーバーエラーの原因調査（laravel.logの記載内容確認）

Xserverを使って、作成したプログラムを本番環境へデプロイしました。
すると、500サーバーエラーが発生（下記画像）。
![500サーバーエラー.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2515610/6e8b4c77-25a3-bdee-be19-54313a4b3af4.jpeg)
↑
画面の中央に、小さく「500｜サーバーエラー」の表示

なにが原因でエラーが出たのか知るため、laravel.logの中身を確認しました。
以下、調査の手順です。

```git bush:ターミナル画面
//XserverとのSSH接続を実施
$ ssh -i C:/　……

//本番環境のディレクトリへ移動
$ cd hogehoge.com/○○/○○/○○(本番ディレクトリ)/

// storage/logsへ移動
$ cd storage/logs/

//laravel.logに記載されているエラー内容を確認
$ less laravel.log
```
以上の手順で、エラーメッセージを確認しました。
エラーメッセージ確認時は、まずshift + >(閉じカッコ）によって、ファイルの一番下まで移動します。
そこから上へさかのぼっていき、[previous exception] [object] のあとに表示されているエラーメッセージを確認しました。
その後は、qキーを押すことでエラーメッセージ確認画面から抜けることができます。

ここまでの手順を把握しておけば、調査～問題解決を自分で対応できるなと思いました。
Codeforces Round #799 (Div. 4)

## A
```c++
void solve(){
	int a, b, c, d;
	cin >> a >> b >> c >> d;
	int cnt=0;
	if(b>a) cnt++;
	if(c>a) cnt++;
	if(d>a) cnt++;
	cout << cnt << "\n";
}
```
## B
```c++
void solve(){
	int n; cin >> n;
	set<int> s;
	for(int i=0; i<n; i++){
		int k; cin >> k;
		s.insert(k);
	}
	int sp = s.size();
	if((n-sp)%2 != 0) sp--;
	cout << sp << "\n";
}
```
## C
```c++
void solve(){
	vector<string> s(8);
	for(int i=0; i<8; i++) cin >> s[i];
	for(int i=1; i<=6; i++){
		for(int j=1; j<=6; j++){
			if(s[i][j]=='.') continue;
			if(s[i-1][j-1]=='#' && s[i-1][j+1]=='#' && s[i+1][j-1]=='#' && s[i+1][j+1]=='#'){
				cout << i+1 << " " << j+1 << "\n";
				return;
			}
		}
	}
}
```
## D
```c++
void solve(){
	string s;
	int x;
	cin >> s >> x;
	string sh = s.substr(0, 2);
	string sm = s.substr(3, 2);
	if(sh[0]=='0') sh = sh[1];
	if(sm[0]=='0') sm = sm[1];
	int h = stoi(sh);
	int m = stoi(sm);
	set<string> st;
	set<string> ss;
	while(true){
		m+=x;
		h+=m/60;
		h%=24;
		m%=60;
		string sh = to_string(h);
		if(sh.size()==1) sh = '0'+sh;
		string sm = to_string(m);
		if(sm.size()==1) sm = '0'+sm;
		string t = sh+":"+sm;
		string rt = t;
		reverse(rt.begin(), rt.end());
		if(ss.count(t)>0) break;
		ss.insert(t);
		if(t == rt){
			if(st.count(t)>0) break;
			st.insert(t);
		}
	}
	//for(auto e : st) cout << e << "\n";
	cout << st.size() << "\n";
}
 
```
## E
```c++
void solve(){
	ll n, s; cin >> n >> s;
	vector<ll> a(n), r(n+1, 0);
	for(ll i=0; i<n; i++) cin >> a[i];
	for(ll i=1; i<=n; i++){
		r[i]+=r[i-1];
		r[i]+=a[i-1];
	}
	//for(auto e : r) cout << e << endl;
	if(r[n]==s){
		cout << 0 << "\n";
		return;
	}
	ll ans=2*n;
	for(ll i=0; i<n; i++){
		ll ac=n+1, wa=-1;
		while(abs(wa-ac)>1){
			ll mid = (ac+wa)/2;
			if(r[mid]-r[i] > s) ac=mid;
			else wa=mid;
		}
		//cout << ac << endl;
		if(ac<0) continue;
		if(ac>=n+1){
			if(r[n]-r[i]==s){
				int del = i;
				if(ans>del) ans = del;
			}
		}
		else if(r[ac-1]-r[i]==s){
			ll ex = ac-1-i;
			ll del = n-ex;
			if(ans>del) ans=del;
		}
	}
	if(ans==2*n) cout << -1 << "\n";
	else cout << ans << "\n";
}
```
RxJS subscribeについて

※用語の使い方多分間違えていますが、感覚として記述。

subscribe・・・処理を実行する。

Observableというものを使うと、
observerというオブジェクトが使える。
この**observerは下記3つの関数を1オブジェクト化したもの**と認識。

```
・next　・・・処理を流す
・error　・・・エラー処理を流す
・complete　・・・処理を終了させる処理を流す
```

下記コードに書いていますが、
observer.next(？);　は、データを流す処理。

データを流すだけでは、処理実行されないので、
subscribe(意味：購買)処理を記述する。

completeは、データ(next)を流す処理を終了させたい時に記述。
このコードを実行すると　→observer.complete(); 
observer.next(5);(下記コード参照)は実行されずに処理が終わります。

<h1>ここでメモした本題は以下</h1>

subscribeは3つの引数を設定できます。

①nextでデータが流れてきた時の実行処理方法
②エラーが発生して流れてきた時の実行処理方法
③complete(データ処理終了)が流れてきた時の実行処理方法

```
const Observabled = Observable.create((observer) => {
  observer.next(1);
  observer.next(2);
  observer.next(3);
  setTimeout(()=>{
    observer.next(4);
    observer.complete(); //completeは引数なし
    observer.next(5);
  },1000);
});

Observabled.subscribe(
  //xに1234のデータが流れてくる。
  (x)=> console.log(`value: ${x}`), //①nextで流れてきたデータをどう実行処理するか。
  undefined,//②エラーが発生して流れたきた場合の実行処理をどうするか
  ()=> console.log("終了");③completeが流れてきた時の実行処理をどうするか。
)

// 結果：
1
2
3
4
終了

```
タグマネージャーでGoogle広告のコンバージョン値を取得（ネットショップASP）

メイクショップASPのECサイトにてGoogle広告を実施。
しかしタグマネージャーでコンバージョン数は取得できても、「コンバージョン値」が発火してくれない。

https://shop26.makeshop.jp/makeshop/newmanager/promotion_optional_aff_popup1.html

結果としては上のリンクにある`[TOTAL_AMOUNT]`や`[TOTAL_PRICE]`といったメイクショップの独自変数は使用せず、完了ページの金額箇所の要素から別途JavaScriptで取得して、値をタグマネージャーに送ることで無事取得してくれるようになった。
![Screen2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2737922/bd5bb612-30aa-f8f3-e7b1-944043fd2531.png)
<h2>①通常通りタグマネージャーを設定する</h2>

https://qiita.com/tetsu-k/items/55847b75b4f8ef6e31b8

<h2>②タグマネージャー側でカスタム変数の作成</h2>
・GTMの変数タイプから、「カスタムJavaScript」を新規作成。
取得したいクラスを指定し保存。（変数名は「合計金額」としておく）

<pre>
function() {
return document.querySelector("p.basketTotalPrice.basketConfirmPrice").innerText.replace(/\D/g,'')
}
</pre>

・Google広告のコンバージョントラッキングタグ内の「コンバージョン値」で先ほど作成した変数`{{合計金額}}`を選択。

![スクリーンショット 2022-07-16 142810.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2737922/57c6314c-1269-c1a6-4b83-3b6190f4f362.png)

<h2>③ECサイト側の設定</h2>
・コンバージョン完了ページの/head内に下記scriptを設置する。
<pre>
&lt;script&gt;
window.dataLayer = window.dataLayer || [];
var totalAmount = document.querySelector(
    "p.basketTotalPrice.basketConfirmPrice").innerText.replace(/\D/g,'');
dataLayer.push({
    'value': totalAmount
});
&lt;/script&gt;
</pre>

<h2>発火確認</h2>
・問題なく配信・発火できているか、タグアシスタントとテストコンバージョンで確認を行う。

<h2>おわりに</h2>
他ネットショップASPについても、クラス名を間違えなければこの方法で取得できそう。
ただし、クラス名など予告なく変更となる場合もあるため、注意が必要。同様の設定でYahoo広告「コンバージョンの価値」についても発火確認済み。
【コピペ】GAS(GoogleAppScript)でimportrangeする方法

#  はじめに
筆者は [大学生限定 プログラミングコミュニティ 『GeekSalon』](https://geek-salon.com/user_trials/new/?utm_source=Direct&utm_medium=attract&utm_campaign=3Q&utm_content=Fukuoka_A1_3Q)で活動している者です！ 

# スプレッドシートでimportrangeをしたいがアクセス権がなくてできない...
みなさんはこのような経験をしたことないでしょうか？
importrangeをしたがアクセス権を許可しないといけない
![スクリーンショット 2022-07-16 14.34.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1081227/20fd0529-dd38-0166-57b4-d783af96d482.png)
アクセス権を許可のボタンを押すと、下の写真のように一生くるくる状態でお手上げ...
![スクリーンショット 2022-07-16 14.34.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1081227/f8402e45-e98f-2359-6cfd-0c08e2635a8c.png)
仕事でどうしてもデータの分析をする必要があり、悩みに悩んだ末...筆者はある方法を閃いたのです！
# GAS (GoogleAppScript) でimportrangeしちゃおう！

```js:

function importrange() {

var copy_ss = SpreadsheetApp.openById("copyしたいスプレッドシートのURL");
var copy_Sheet = copy_ss.getSheetByName('copyしたいスプレッドシートのシート名');
var copy_Data = copy_Sheet.getDataRange().getValues();

var arr =[]
for (let i = 1; i < copy_Data.length; i++) {
  var area         = copy_Data[i][1]  
  var name         = copy_Data[i][4]  
  var university   = copy_Data[i][5]  
  var date         = copy_Data[i][12]  
  var channel      = copy_Data[i][8]
  var asign        = copy_Data[i][11]

  if (area == '東京' && (channel === "ref" || channel === "tel")) {
    arr.push([date,name,university,asign,channel])
  }
}

var target_ss =SpreadsheetApp.getActiveSpreadsheet();
var target_sheet = target_ss.getSheetByName('ペーストしたいスプレッドシートのシート名');

target_sheet.getRange(2, 1, arr.length, arr[0].length).setValues(arr); 

}

```


##  最後に
いかがでしたでしょうか？
不具合等ありましたらご連絡ください！
詳細の解説はまた時間がある時にやろうと思います！今回はとりあえずコピペで使えるところまで！
それではご覧いただきありがとうございました！
RaspberryPiPicoSDKのビルド環境をDocker＋Jenkinsで構築する


# やりたいこと

RaspberryPiPicoSDKを使ったプログラムをビルドする環境をDockerコンテナに構築して、Jenkinsからビルドできるようにする。


# 手順

### DockerコンテナでPicoのビルド環境を準備する

https://qiita.com/ryot0/items/56a296b33111408595c6


### DockerコンテナにJenkinsを構築する

https://qiita.com/ryot0/items/e43d825e8616810d86bb


### Dockerコンテナにgitサーバーを構築する

https://qiita.com/ryot0/items/d9b7ab4b7786b0b2e61f


### Dockerコンテナにsambaを構築する

https://qiita.com/ryot0/items/f98ca54f5c3b748b0c12


### コンテナ間で通信できるようにネットワークを設定する

https://qiita.com/ryot0/items/a5aa80e45355b1e60295


### Jenkinsをインストールしたコンテナでssh-keyを生成する

```shell
ssh-keygen -t rsa -b 4096
```

公開鍵はgitをインストールしたコンテナに登録しておく。


### Jenkinsに秘密鍵を設定する

Jenkinsの管理　→　Manage Credentials

 - スコープ：　グローバル
 - ID：　jenkins
 - 説明：　/data/app/root/jenkins/.ssh/id_rsa
 - ユーザー名：　jenkins
 - 秘密鍵：　直接入力


### Jenkinsの環境変数を設定する

Jenkinsの管理　→　システム設定　→ 環境変数

 - PICO_SDK_PATH
    - /data/app/root/pico-sdk
 - SHARE_PATH
    - /data/share/root

PICO_SDK_PATHはPICOのビルド用。
SHARE_PATHは成果物を配置する場所。


### ジョブを作成する

新規ジョブ作成

 - 名前：　pico-playground-master
 - 説明：　Playground
 - ソースコード管理：　git
    - ssh://pi@sshgitcont01:2222/data/app/root/repos/playground.git
    - 認証情報：　jenkins
- シェル実行
    - ./build.sh
- 成果物を保存
    - build/*.uf2


### build.sh

```shell:build.sh
#!/bin/bash

set -xe

echo start build: $WORKSPACE
cd $WORKSPACE
mkdir -p build
cd build
rm -rf ./*
cmake ../src
make -j4
cp *.uf2 $SHARE_PATH/$JOB_NAME/
echo end build: $WORKSPACE
```

main.uf2が/data/share/rootに配置されます。このディレクトリはホストのディレクトリがマウントされています。
さらに、このディレクトリはSambaコンテナにもマウントされており、Samba共有ディレクトリを母艦PCから参照することで成果物をダウンロードすることができます。
一々、Jenkinsからダウンロードボタンを押してダウンロードしてくるよりこっちの方が楽かも。
solidjsで困ったところメモ

# 1. Storeがよくわからない
ストアという言葉に混乱したけど、シンプルに「オブジェクトをリアクティブに使える仕組み」のようです。
vue3の`reactive()`みたいな感じかな？

vuexとかreduxのようなグローバルなステート管理の話ではないです。
↑ずっとこういう話だと思いこんでいて、公式サイトを読んでもさっぱり意味がわからなかった…

>#ストア
これらの API は solid-js/store で公開されています。これにより、Signal のツリーを個別に追跡・変更できるプロキシオブジェクトであるストアを作成できます。
（公式サイトより）

solidjsの`createSignal`や`createStore`は`export`しておけばどこからでも`import`して使えるので、特別にグローバルなステート管理の仕組みは必要ないようです。

## 参考
https://qiita.com/shadowTanaka/items/419dc9e7db98971ff818
こちらの記事が大変参考になりました。
というかこちらの記事がなければ理解出来なかったと思います。
大感謝。

# 2. `input`の`onChange`が想像通りに動かない
`onInput`を使います。

## 参考
https://typeofnan.dev/how-to-use-onchange-in-solidjs/

#3. icon
font-awesomeとか使いたいけど専用パッケージ無いな〜とか思ってたら強いのがありました。
https://solid-icons-web.vercel.app/

***
随時加筆します。
LTSpice上で周波数重み付け特性A再現

# 動機
オーディオ用途のアンプを設計するにあたり、周波数重み付け特性A（下図参照）をした雑音計算がしたくなった。

参考：日清紡マイクロデバイス（旧新日本無線）NJU72322データシートより抜粋
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527090/998e77d3-5a7c-e87e-86ae-6bd02ac00a45.png)

20kHz以上の可聴帯域外の成分を落とした上で計算された雑音のため、
LTSpice上で何もケアせずに雑音計算すると、見かけ上かなりノイジーなSIM結果が出てくる。
善し悪しの判断がしにくいため、今回模擬フィルタを作ることにした。

オーディオの規格については不案内のため、誤解が紛れ込んでいる可能性があるので
有識者には助言いただければ幸いである。


# 周波数重み付け特性Aとは
国際規格としては「IEC 61672-1 Electroacoustics - Sound level meters - Part 1: Specifications」に記されたレベル計(騒音計）の規格に示されたフィルタ特性。いわゆるラウドネス特性を反映した人の聴覚特性を再現するためのもの。
日本では、JISが同規格を参照している
「JIS  C 1509-1　電気音響−サウンドレベルメータ（騒音計）− 第1部：仕様」　に実質的な同内容が記されている。
以後、JISを前提に話を進める。
今回は「表3−周波数重み付け特性及び受容限度値」に示されたAの特性をLTSpice上で気合で再現した。

# 再現結果

回路的には2次LPFと3次HPFの合成特性で再現できた。
概形だけならサクッと再現できるが、特性受容限度のクラス１に収めようとするとかなりシビアなチューニングを要した。
付属書Eの数式表現も見たが正直LTSpiceのラプラス応答に綺麗に落とし込めなかったのと、この人力チューニングの方が表３の特性と一致していると思う。
ただ、このパラメータを元に実機オペアンプでアクティブフィルタを組んでも
部品ばらつきで特性受容限度のクラス１に収めるのは厳しい気がする。
こだわるのであればデジタル的なチューニングが可能な形で測定系を組む方がよさそう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527090/96fd17d2-b157-e0d3-8d68-cce4defedf2e.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527090/344edfe1-488f-4d39-a8a9-05d551e48e98.png)

# ノイズ測定フィルタ影響確認

今回作成したフィルタを通すことで、ノイズ測定にどの程度の影響がでるか確認した。
秋月で買える5V単電源オペアンプAD8616でバッファアンプを組んでみた時の特性をSIMしてみた。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527090/b4be6e2b-91c7-bc6a-ec31-c495cbfa588a.png)

V(out)がオペアンプの生の特性、V(a-weight)がフィルタを通した時の特性。
1kHz以下と10kHz以上の伝達特性が結構落ちていることがよくわかる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527090/b5a8748a-6685-a72e-454b-4179cb2b6395.png)

同じ回路で10Hz～20kHzのノイズをSIMした結果がこちら。
ざっくり２割減っている。
|    |  Total RMS noise  |
| ---- | ---- |
|  AD8616生出力雑音  |  1.1062uV  |
|  AD8616周波数重み付け特性A雑音  |  0.8756uV  |

# 終わりに

上述の人力チューニングで３時間ぐらいかけたので褒めてほしい。

元気のいいアンプだと1MHzぐらいまで帯域が伸びていたりするので
オペアンプの生のノイズと、人間の聴覚特性を踏まえたノイズとの乖離が大きくなっていくことは想像に難くない。

いい勉強になった。
Google Spread sheet // query関数を使ってみた

複数のシートから情報をまとめて表示させたいという事情があって、どういう方法があるか調べた結果、Query関数ならいけそうということで試してみました

# Query
```function
=query({
query(A!$A:$D,"select * );
query(B!$A:$D,"select * );
query(C!$A:$D,"select * );
query(D!$A:$D,"select * )
})
```
シート名A,B,C,DのA列～D列を全部くっつけて表示させる場合

※select * はなくても大丈夫らしいけど、個人的にはわかりやすいのでつけてます

https://support.google.com/docs/answer/3093343?hl=ja
SQLアンチパターンを簡単にまとめてみた

# はじめに
SQLアンチパターンを読んだので簡単にまとめてみました。

https://www.oreilly.co.jp/books/9784873115894

内容としては、論理設計に関するアンチパターンのみを挙げております。
* [カンマ区切りで値を格納する](#カンマ区切りで値を格納する)
* [同じテーブルにある別行を参照する階層構造を持つ](#同じテーブルにある別行を参照する階層構造を持つ)
* [反射的に id のような代替キーを使用する](#反射的に-id-のような代替キーを使用する)
* [外部キー制約を使用しない](#外部キー制約を使用しない)
* [1つのカラムに複数テーブルの参照を持たせる](#1つのカラムに複数テーブルの参照を持たせる)
* [同じ意味を持つ値を格納するカラムを複数定義する](#同じ意味を持つ値を格納するカラムを複数定義する)
* [データを含む列名やテーブル名を定義する](#データを含む列名やテーブル名を定義する)

# カンマ区切りで値を格納する
|部署名 |社員番号 | 
|--- |--- |
|経理部 |1,2,3 |
|開発部 |4 |
|営業部 |5,6 |

## アンチパターンである理由
* とにかくクエリの生成がしづらい。
* 定義する文字列の長さに根拠を示せない。
→ 将来においても対応し得る長さであるか？

## 解決策  
多：多の関連を持つ中間テーブルを作成し、値を1行ずつ格納する。

# 同じテーブルにある別行を参照する階層構造を持つ

|組織名 |組織ID |親組織ID | 
|--- |--- |--- |
|親組織 |1 |NULL |
|子組織 |2 |1 |
|孫組織 |3 |2 |

## アンチパターンである理由
* 深い階層であればあるほど取得するクエリにおいて JOIN の数を増やす必要がある。
* 親を削除する場合に子孫から順番に削除する必要がある。 

## 解決策
長所と短所を見極めながら、以下のような代替ツリーモデルを使用する。
* 経路列挙モデル
階層をパスとしてテーブルに格納しておく。
* 入れ子集合モデル
階層関係を子孫の集合関係として捉えて、nsleft および nsright と呼ばれる数値で関係を表す。
* 閉包テーブルモデル
階層のパスを示すテーブルを作成し、直接の親子関係だけでなく全体のパスを格納する。

# 反射的に id のような代替キーを使用する

## アンチパターンである理由
* 制約の指定漏れにより重複行が生じる恐れがある。
* カラム名を「id」とした場合、キーの意味が分からなくなる。

## 解決策  
本当に必要な場合のみ用いる。
必要な例）ORMフレームワークを用いて開発を行っている場合

# 外部キー制約を使用しない

## アンチパターンである理由
* プログラムのコードに不具合があった場合に不正なデータが登録可能となる。
* 長期間運用していると予期せぬデータの不整合が発生する恐れがある。

## 解決策
外部キー制約を用いる。

# Key・Valueカラムを持つテーブルを作成する
|key |value | 
|--- |--- |
|TYPE |error |
|DATE |2022/07/16 |
|MESSAGE |NULLは登録できません。 |
|TYPE |success |

## アンチパターンである理由
* データ型や必須属性を活用できない。
* key に一貫性がない場合はデータの取得が困難となる。

## 解決策
状況に応じて適切なテーブル設計を用いる  

例）シングルテーブル継承
格納し得るすべてのタイプの属性を個別の列に格納する
|type |date |message | 
|--- |--- |--- |
|error |2022/07/16 |NULLは登録できません。 |
|success | | |

# 1つのカラムに複数テーブルの参照を持たせる
|顧客名 |住所タイプ |住所ID | 
|--- |--- |--- |
|山田太郎 |配送先  |1 |
|鈴木花子 |本人宅 |2 |
|山田太郎 |本人宅  |3 | 

|配送先ID |配送先 | 
|--- |--- |
|1 |東京都 |

|本人宅ID |本人宅 | 
|--- |--- |
|2 |大阪府 |
|3 |東京都 |

## アンチパターンである理由
* 外部キー制約ではテーブルを1つだけ指定しなければならないため、外部キー制約を定義できない。
* 複数テーブルへの参照を持つ場合、動的に JOIN を行うことができない。

## 解決策
中間テーブル、または共通の親テーブルを作成する。

# 同じ意味を持つ値を格納するカラムを複数定義する

|商品名 |分類1 |分類2 |分類3 | 
|--- |--- |--- |--- |
|パソコン |電子機器 |IT | |
|炊飯器 |家電 | | |
|iPhone |IT |スマホ |電子機器 |

## アンチパターンである理由
* 値の検索や追加、削除が困難となる。
* 同様の値が存在しないこと（一意性）の保証ができなくなる。

## 解決策
従属テーブルを作成し、値を複数の列ではなく1行ずつ持たせるようにする。

# データを含む列名やテーブル名を定義する
* Customers_2021 テーブル
* Customers_2022 テーブル
* Customers_2023 テーブル

## アンチパターンである理由
* データごとに列やテーブルを作成する必要があるため、どんどん数が増えていく。
* データの更新によって不正な行が生じる恐れがなる。
例）2021年のテーブルに誤って2022年のデータを登録したので、該当のデータを正しい値に更新した。
→ 更新するのではなく、2022年のテーブルに移動（削除および新規登録）する必要がある。

## 解決策
パーティショニングとテーブルの正規化を行う。
「文系だからプログラミングが苦手」は間違っている

文系とか理系とかぶっちゃけ関係ないと思っています。
どこの畑の出身かは関係なく、その畑でどのように行動してきたかが重要だと思っています。
つまりは因果関係を間違えているのではないかと。

理系出身でプログラミングが苦手な人も見てきましたので、尚更そう思います。

# 理系＝勉強時間が長い→地頭良くなる＝プログラミングができる

このような関係じゃないかと思っています。
理系は積み上げ式の学習が多いため、勉強時間が必然的に長くなります。
思考している時間が長いとも言い換えられるでしょう。

だからこそどんどん思考力が上がっていきます。
思考する力があるからこそプログラミングができる。

# 文系=勉強時間が短い→地頭が良くなりにくい=プログラミングが苦手

文系（少なくとも今の日本の大学は、ですが）はあまり勉強しなくても乗り越えていけちゃいます。だからこそ思考する癖ができていなかったり、考えることに対しての耐久力がないのではないかと思います。
**逆に言えば、文系でもきちんと思考してきた人はプログラミングができます。** 少なくとも私の周りはそうです。文系未経験だろうが積み上げ式の学習にきちんと耐えることができ、「どこまで理解すれば良質なアプトプットを出せるのか」も分かっています。（かく言う私はそこまでできてないんですけどね）

# 向き不向きは「思考の積み上げ」で決まる

向き不向きの様々な要因はあると思いますが、これも一つの大きな要因だと思います。
異論、バシバシ待っています。
初心者　MySQL8に挑戦する 4

# 今日はこっちでやってみる

https://www.amazon.co.jp/MySQL徹底入門-第4版-MySQL-8-0対応-yoku0825-ebook/dp/B088M1BMBG/ref=sr_1_1?crid=19Q9HIPU4SI7Q&keywords=mysql+徹底入門&qid=1657934534&sprefix=MySQL%2Caps%2C248&sr=8-1

- mysql -u root -p（起動）
- show databases（DB一覧）
- use AETATUM（選択）
- show tables（table一覧）
- drop table MUNDI（削除）

 削除してみた。一覧を見るときはtablesで複数、消すときは一つだけだから単数、という基礎英語力。

　さて、テーブルを作り直す。今回はnull許容とか、未記入の場合の初期値とか、入れてみようと思う。terminalは使いにくいから、テキストエディタでいこう。

- テーブルの項目は分かち書き（項目ごとに改行）でもいけると判明。見やすくなった。
- geometryをいったん放棄して、intと文字列だけにする。
- nullを許容しない設定はできたが、初期値が入ってくれない。
- 練習なので、実際必要な全項目を一気に入れるのは諦める。めんどうすぎ。

　さて、データを入れてみよう。fileで一気に､という方法がこちらでは見当たらないので、一個ずつ入れる。

- ERROR 1064 (42000): You have an error in your SQL syntax;

　なにがきらわれているのか理解するのにだいぶ時間が掛かったが、どうも単語じゃない項目が引っかかる。例えば「Siege of Paris」が入らない。それで「Siege_of_Paris」にしたらエラーは消えた。ちなみにハイフンはダメ、キャメルケースはOKだった。

 ところが、さらに

- ERROR 1054 (42S22): Unknown column '‘Siege_of_Paris’' in 'field list'

　同じ項目だけど、エラーの種類が変わっている。これ、よーく見ると、エラー文のシングルクオートと、文字列を囲っているシングルクオートの角度がちょっと違う。エラー検索をかけたら、出てきたのは・・・

## コピペはしちゃだめ、文字化けてエラーになるから。

　だそうです。･･･やっぱterminalで打たなきゃダメなのかい。まあいいや、だいぶ慣れてきたし。ということで、直打ちしたら、無事通りました。同じkeyなのにねえ。
　今にして思えば、初期値が入らなかったのも、同じ理由かもしれない。

　四苦八苦して、データ一つですか。でも、フロントに繋ぐ前に、もう少し練習しましょう。

https://qiita.com/dongri727/items/92b9cb412f91980f6003

https://qiita.com/dongri727/items/be64695a70f1481fdd26
AWS RDSのリードレプリカを書き込みできるようにするには（自分用メモ

通常、Amazon RDS DB インスタンスのリードレプリカは、読み取り専用に設計されている。

Amazon RDS for MySQL または MariaDB を使用している場合は、読み取り/書き込みになるように DB インスタンスのリードレプリカを設定できる。
これは、DB インスタンスに関連付けられている DB パラメータグループの read_only パラメータを false に設定することで可能になります。
※Amazon Aurora などの他の Amazon RDS エンジンを使用している場合、read_only パラメータを変更することはできない。

注意: レプリカで書き込みを有効にしても、バックアップ、復元、およびフェイルオーバーなどのオートメーションには影響しない。
　　　ただし、書き込みの影響を理解せずに書き込みを実行すると、不整合、またはレプリケーション障害の原因になる場合がある。

Amazon RDS DB インスタンスのリードレプリカを読み取り/書き込みに設定するには、

１、MySQL または MariaDB インスタンス用に DB パラメータグループを作成。
２、パラメータグループを変更。
３、RDS DB インスタンスを DB パラメータグループに関連付け。
注意: DB パラメータグループを指定せずに DB インスタンスを作成すると、デフォルトの DB パラメータグループが使用されます。つまり、デフォルトのパラメータグループは変更できません。このインスタンスに関連付けられているカスタムパラメータグループが既に存在するという場合は、新しいパラメータグループを作成する必要はありません。DB パラメータグループの詳細については、「DB パラメータグループを使用する」を参照してください。
Pythonでマークダウンをパースして、快適なプログラミング記事作成環境を作る

先日、社内のホームページで、プログラミング活用の事例紹介をしてほしいとの依頼がありました。
いくつかの記事をHTMLで直接書いてみたのですが、これじゃ続かないと思い、マークダウンで書くことにしました。

PythonでマークダウンファイルをHTMLに変換することにし、シンタックスハイライトできるように工夫しました。

使用するPythonライブラリは

* [python-markdown](https://python-markdown.github.io/)
* [jinja2](https://jinja.palletsprojects.com/en/3.1.x/)

シンタックスハイライトは[Prism.js](https://prismjs.com/index.html)を使用します。Prism.jsはあらかじめダウンロードページで、必要なオプションをチェックし、cssファイルとjsファイルをダウンロードしておきます。（今回はPythonとLine Numbersを追加でチェックしました。）

マークダウンファイルは次のように用意し、contents.mdというファイル名で保存しておきます。

````markdown
# Hello World!

lorem ipsum

lorem ipsum
lorem ipsum
{ style='font-size: 2rem; color: red;' }

``` { .python .line-numbers }
import os
```
````

ここでポイントは、{...}の中の記述です。通常のマークダウン記法ではないのですが、このようにするとpython-markdownの拡張機能で、シンタックスハイライト用のclassをつけることができます。
styleも記述できるので、画像の大きさなど細かく記事を調整できるのではないでしょうか。
その他の拡張機能は[こちら](https://python-markdown.github.io/extensions/extra/)です。

マークダウンファイルをHTMLに変換するPythonのコードは次にように記述します。extensionsで、上記拡張機能を追加します。
HTMLはJinja2を使ってテンプレートに記事を流し込むようにしました。

```python
from jinja2 import Template
from markdown import markdown

with open('contents.md') as f:
    text = f.read()

extensions = [
        'attr_list',  # HTMLにクラスなどを付与できる
        'fenced_code',  # コードのシンタックスハイライト用
        ]
contents = markdown(text, extensions=extensions)

template = Template("""
<!DOCTYPE html>
<html>
<head>
  <meta charst="UTF-8">
  <title>Markdown</title>
  <link rel="stylesheet" href="prism.css">
</head>
<body>
  {{ contents }}
</body>
</html>
""")

html = template.render(contents=contents)

with open('output.html', mode='w') as f:
    f.write(html)
```

![Screenshot 2022-07-16 12.44.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2591762/cae1826e-a578-b53b-1125-a53fddb6d259.png)

できました！
Tech系Youtubeチャンネル（個人）

YoutubeのTech系動画を家事や散歩をしながらバックグラウンド再生して聴くのが好きです。
個人が配信しているチャンネルを紹介します。

[公式チャンネルはこちら](https://qiita.com/tetsuyaohira/items/cb55bfb2a7f22509d4a0)
[カンファレンスはこちら](https://qiita.com/tetsuyaohira/items/3003c9ef578ac5f28dd5)

# 日本語
## AIcia Solid Project
https://www.youtube.com/channel/UC2lJYodMaAfFeFQrGUwhlaQ
## deisui html
https://www.youtube.com/c/deisuihtmlradio
## hanhan1978
https://www.youtube.com/user/hanhans1978
## Joichi Ito
https://www.youtube.com/c/JoichiIto
## Ossanfm
https://www.youtube.com/c/ossanfm
## Regonn&Curry fm
https://www.youtube.com/channel/UCeV1Kv4oLud2h6a3dU49z6Q
## resizefm
https://www.youtube.com/c/resizefm
## Ryuichi Ueda
https://www.youtube.com/c/ryuichiueda
## マフィア先生のエンジニア
https://www.youtube.com/c/弱小IT社長の奮闘記CodeMafia/featured
## ゆるコンピュータ科学ラジオ
https://www.youtube.com/channel/UCpLu0KjNy616-E95gPx7LZg
## 紅月(koduki) / テックポエムCh
https://www.youtube.com/user/kodukimisuzu
## devaslife
https://www.youtube.com/c/devaslife
## hak & tomzoh
https://www.youtube.com/c/haktomzoh
## Jxck Jxck
https://www.youtube.com/user/jackcdanny
## KOBA789 / Channel 78.9
https://www.youtube.com/c/KOBA789
## Off Topic / オフトピック
https://www.youtube.com/c/OffTopicJP
## やっすんのエンジニア大学
https://www.youtube.com/channel/UCajrdoGzHzDogrNrLYYmGsg
A8%98CodeMafia
## 徳丸浩のウェブセキュリティ講座
https://www.youtube.com/c/hiroshitokumaru
# 英語
## Dev Ed 
https://www.youtube.com/c/DevEd
## daily dev
https://www.youtube.com/c/dailydev
## mayuko
https://www.youtube.com/c/hellomayuko
Mediumやnoteみたいなブログの投稿フォームでは「タイトル」と「本文」の区切りがないのがモダンやで

# Medium の例

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89618/75ed34e1-dc4b-c735-3b77-05183c674043.png)

タイトルと本文の間に明確な区切りがないのが分かるだろうか。

PCから操作すると上下キーでシームレスにフォームを移動して、タイトルと本文の両方を編集することが出来る。
というより厳密にはタイトルと本文の区切りがない。

- 1個フォームだけがある。
- 本文の1行目が自動的にタイトルになる。

ちなみに「note」という日本のブログサービスもこの仕様に追随している。

# 何が良いの？

「入力欄の間の移動コスト」がゼロだ。なぜなら入力欄が1個しかないからだ。

ブログの書き方は

- タイトルを付けてから本文を書く
- 本文を書いてからタイトルを決める
- 仮タイトルをつけてから本文を書き、また正式なタイトルをつける

というパターンがあるが、このフォームのスタイルだと、頻繁に起こる「タイトルと本文の行き来」のコストを極限に低く出来る。

# タイトルを考えなくても良い

1行目が自動的にタイトルになるので、結果としてユーザーが意識的にタイトルを決めなくても、自動的にタイトルが決まる。

ブログを書く時の最大の敵は「書く始める時の面倒さ」である。
「タイトルを考える」という労力は意外に大きい。

なので「タイトルをつけずともタイトルがつく」という、これは一挙両得の素晴らしい仕様だと思う。

考えることが2個から1個に減るので、パーセンテージにすると50%の削減だ。

# 「ユーザーが決めなければいけないこと」は少なければ少ないほど良い

ブログサービスのような、サービスの命である「記事を書くこと」という「メイン行動」のコストを下げ、ユーザーエクスペリエンスを上げるのは必須の課題である。

# 何故、他の旧来のブロブサービスは「タイトル欄」を残し続けるのか

端的に言えば、何も考えていないからだと思う。

UXに無頓着なのだ。

だからこういうことになる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89618/78ef0f32-f597-e182-7a58-7226d5b9457a.png)



# つぶやき

いつか書きたかった記事がようやく書けた。

<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
【PC・スマホ両対応】CSSだけでモーダルの背景をスクロールさせない新しい方法（つっかえ棒式モーダル背景固定法）

スクロールチェーンを防ぐための「overscroll-behavior: contain」を応用した方法をご紹介します。
名付けて「つっかえ棒式モーダル背景固定法」です。

ソースコードはこちら
https://github.com/gorimatyan/css-modal-nonscroll

# 目次

[1.対象読者](#1-対象読者)
[2.モーダルの構成](#2-モーダルの構成)
[3.つっかえ棒で簡単解決](#3-つっかえ棒で簡単解決)
[4.まとめ](#まとめ)
[5.追記](#追記)


# 1. 対象読者
↓ モーダルの後ろがスクロールされてしまう人
![1657935999499.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1311883/263e7bb9-b201-da86-5518-34d1ea2e9042.gif)

# 2. モーダルの構成

![1657939434485.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1311883/ae980798-0f4f-8c34-396d-d92a608befa8.jpeg)
```html
/* index.html */
<main id="container">
    <div class="modalWrapper">
        <div class="modal">
            <header>ヘッダー</header>
            <p>今日も頑張ろう</p>
        </div>
    </div>
</main>
```

# 3. つっかえ棒で簡単解決
## 結論

![1657941451735.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1311883/ea492f63-3012-97b9-4747-7e2c08938167.jpeg)

## 手順

### ①つっかえ棒を設置する
modalの下にdiv要素を一つ書きます。
```diff_html
/* index.html */
<main id="container">
    <div class="modalWrapper">
        <div class="modal">
            <header>ヘッダー</header>
            <p>今日も頑張ろう</p>
        </div>
+       <div class="nonScroll"></div>
    </div>
</main>
```
このnonScrollとやらが図にある黄色の「つっかえ棒」です。

## ②CSSを書く
modalWrapperとnonScrollにCSSを設定するだけでモーダルの背景がスクロールされなくなります。


```css
.modalWrapper {
    display: flex;
    overscroll-behavior: contain;
    overflow-y: scroll;
}
.nonScroll {
    height:calc(100vh + 1px) ;
    width: 1px;
    background-color: transparent;
}
```

::: note info
<b>なぜスクロールされなくなる？</b>
まずモーダルと背景が二層 (z-index) になっていると考えてください。

モーダル全体を囲むmodalWrapperに「overscroll-behavior」と「overflow-y」を設定することで、手前にあるモーダル全体がスクロールの対象になります。
よって、モーダル全体(modalWrapper)に覆われている背景はスクロールされなくなるという理屈です。
:::

### 

# まとめ
:::note info 
あなたの作っているモーダルに対して
①<b>モーダルを構成する親要素に</b>.modalWrapperのCSSを当てる
②<b>その子要素に</b>div.nonScrollを配置し上記のCSSを当てる
:::

実際に見てみたいという方はワタクシのGitHub貼っときますので覗いちゃってください。
https://github.com/gorimatyan/css-modal-nonscroll

# 追記
Twitterにてatomsphere5様が改良したものを載せております！
<b>改良前：HTMLにdiv.nonScrollを追加 
→ 改良後：疑似クラスで作成することで完全にCSSのみで実装可能に</b>
下記ツイートのリンクからコードサンドボックスでデモが見られるので是非ご確認ください！！


<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">これは知らなかった<br><br>「CSSだけで」とあるので新規に.nonScrollを追加しないといけないの勿体無い気がしたので、前後に擬似クラスbefore、afterにて同じ思想で実装しなおしてみた。<br><br>モーダルの表示自体はJavascriptだが、本当に完全にやりたければcheckboxとforでも実装可<a href="https://t.co/JEDpeuafcw">https://t.co/JEDpeuafcw</a> <a href="https://t.co/FQ1as7rhDN">https://t.co/FQ1as7rhDN</a></p>&mdash; わかるたくと@エンジニアが足りない (@atomsphere5) <a href="https://twitter.com/atomsphere5/status/1548336398146883584?ref_src=twsrc%5Etfw">July 16, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
読書感想文：DXを成功させる データベース構築の勘所

## はじめに
https://www.amazon.co.jp/dp/4296111930

「[DXを成功させる データベース構築の勘所](https://www.amazon.co.jp/dp/4296111930)」の本を読みました。
その感想です。

### 参考になったところ
DWH（Data Ware House:データウェアハウス）で実際に使用するクラウドサービスの全体像の俯瞰として手に取りました。
結果としては、その目的に沿った内容でした。

[目次](https://bookplus.nikkei.com/atcl/catalog/22/285840/)より
```
第1章 DX の要、変わるデータ基盤
第2章 実践、データ基盤構築
第3章 NoSQL データベース
```
とあります。特に第2章が参考になり、具体的な選定イメージが湧きました。

### 紹介されているクラウドサービス
AWS, GCP, Azureの3つを中心に主要なDBの紹介があります。
特にAWS周りの話を知りたかったのですが、比較として他のサービスを知れたことがよかったです。
2022年発売の本ということもあって[Amazon Aurora](https://aws.amazon.com/jp/rds/aurora/)のコスト感やメリットが知れたり、
[Amazon Redshift](https://aws.amazon.com/jp/redshift/)のRDBMSとは違う使い方のDBイメージが把握できたのは本書を読む目的を果たせました。
S3との連携が可能な点や、次世代の[RA3というインスタンス](https://aws.amazon.com/jp/redshift/features/ra3/)の扱いがあることなど。

列単位と行単位の違いが大きく、行単位だとSQLのクエリ実行時は全体（行）を検索する認識でしたが、
列指向データベースは、列単位のメリットを活かす基本的なことを知れてよかったです。
合わせて本書紹介の[Google BigQuery](https://cloud.google.com/bigquery?hl=ja)の歴史とRedshiftの比較がためになりました。
特に「Redshiftは時間課金で、BigQueryはクエリー課金（P.88)」の一文は覚えておきたいです。

### まとめ
コードが一行も出て来ず、ネットで単語を一つずつ丁寧に検索すれば出てくる情報かも知れませんが、
本としてまとまっていることが本書の魅力と感じました。
DWH周りの求められていることをざっくり知りたいと思った私のような人には向いていると思います。

例：[Amazon DocumentDB（MongDB互換）](https://aws.amazon.com/jp/documentdb/)サービスなんてあるのか知識レベルの人向け

150ページもない書籍なのでまずはざっくり知りたいのレベルの人の手がかりにオススメです。
配列内の数字の合計（同じ数字を除く）

# はじめに
2回目の問題だったのに解けなかったので、学習の復習のために投稿します。
回りくどくなるかもしれませんが、できるだけ自分の言葉で説明できるようにするつもりです。

# 環境
ruby 2.6.5

# 問題
3つの数字が格納された配列が与えられています。
この配列に格納された数字の合計値を出したいのですが、条件として、配列内で重複している数字に関しては除くことが求められています。

``` ruby
def lone_sum(ary)
  # 処理を記述
end
# 呼び出し例
lone_sum([1, 2, 3])
```

# 考え方
以下の手順で考える
1. 配列内で重複する数字があるかを確認する
2. 重複数字を除いたユニークな配列を作る
3. ユニークな配列に格納された数字を合計する　

## 1. 配列内で重複する数字があるかを確認する
配列に格納された数字をa, b, cとします。
まずはaの数字に対して、それぞれの配列内の数字を比較して同じかどうかを確かめます。
同じ場合にはカウントが上がるようにします。
例えば、aとa、aとb、aとcの数字を比較してカウントが上がるので、
カウントが2以上であれば重複する数字があるということになります。

``` ruby
def lone_sum(ary)
  ary.each do |num|
    count = 0
    ary.each do |n|
      if num == n
        count += 1
      end
    end
  end
　end
```

## 2. 重複数字を除いたユニークな配列を作る
まず、ユニークな配列を格納する変数を定義します。
`uniq_ary = []`
上記で確認した重複しない数字をこのユニークな配列に格納します。
`uniq_ary << num`

ここまでをまとめると、
``` ruby
def lone_sum(ary)
  uniq_ary = []
  ary.each do |num|
    count = 0
    ary.each do |n|
      if num == n
        count += 1
      end
    end
    if count < 2
      uniq_ary << num
    end
  end
end
```

## 3. ユニークな配列に格納された数字を合計する　
あとはuniq_aryの中身を合計するだけです。
``` ruby
sum = 0
uniq_ary.each do |uniq_num|
  sum += uniq_num
end
```

# 解答コード
``` ruby
def lone_sum(ary)
  uniq_ary = []
  ary.each do |num|
    count = 0
    ary.each do |n|
      if num == n
        count += 1
      end
    end
    if count < 2
      uniq_ary << num
    end
  end
  sum = 0
  uniq_ary.each do |uniq_num|
    sum += uniq_num
  end
  puts sum
end
```

# 終わりに
自己代入演算子の+=を=+と表記すると計算結果が変わりました。
なぜなのか現段階ではわからないので引き続き調べていきたいと思います。

# 追記（2022.7.20）
コメントでtallyメソッドやsumメソッドを使用するコードをご教授いただきました。
[配列内の数字の合計（同じ数字を除く）再考察](https://qiita.com/pipiyoyoyo/items/b7ff4109cc6b62f6ce2f)
こちらにもまとめてみました。

また、自己代入演算子の件についてもコメントいただいたので、そちらご参照ください！

ありがとうございます！！
LINEなどのアプリで何故リンクは開かれないのか？何故埋め込みの画像・動画に劣るのか？

Webではリンクを開くことは必須の行為だが、アプリで「リンク先を開く」ということには不思議と抵抗感がある。

たとえばどんなアプリでも、画像や映像がそのまま埋め込まれる方が、ずっと目に触れる。まあ当たり前といえば当たり前だが。

だがどうしてリンク先を開くことに、僕らはこんなに怯えているのだろうか？

# 理由: ロードのコスト

リンク先を開くにはロードの時間がかかる。まずここが不利だ。

アプリ内で画面遷移せずにそのまま見られる画像、動画とはまるでコストが違う。

それが1秒であっても2秒であっても、大きなコストだ。

# 理由: 未知コスト

リンク先がそもそも何なのか分からない。だから僕らは開くのをためらう。

Webページかもしれないし、Youtubeかもしれない。
リンク先にウィルスが埋め込まれているかもしれない。たとえそれが現実の不安であれ、妄想の不安でにせよだ。

LINEなどのアプリはある程度、リンク先情報を展開して見せてくれるが、それでも未知のコストはゼロにはならない。

# 理由: 認知のスイッチングコスト

リンク先を開くとき、僕らは今使っているアプリを離れて、別アプリを使わなければいけなくなる。
(それがアプリ内のインラインブラウザにせよだ)

ここでスイッチングの認知コストが発生する。

それに加えてだ、リンク先からアプリに戻ってくる時は戻ってくる時で、またアプリ切り替えのコストがかかることになる。つまりスイッチングコストは往復で2回かかるのだ。これは大きい。


<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
git stash周りで困ったこと

# git stash周りで起きた問題の対処と理由

### 今回起こった問題
個人でgitを使って開発をしていた時に起こった問題。
デフォルトのブランチを、masterブランチからmainブランチに変えたかった。そのために行ったこととしては、

作業をしていたmasterブランチでgit stash -u(変更内容を退避)
↓
git checkout main(mainブランチに移動)
↓
mainブランチでgit stash apply 0(変更内容を復元)
↓
大量にエラーが出て、それが何故か分からなくて困った

### なぜ起こったか
![スクリーンショット 2022-07-16 12.25.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648402/9e472669-2580-34ec-109b-d8a5e8c26575.png)


### どうやって解決したか
それぞれの変更やコンフリクトを解消して変更点をなくす
↓
git checkout master(masterブランチに移動)
↓
masterブランチでgit stash apply 0(変更内容を復元)
↓
git add .
git commit -m "メッセージ"
git push origin master
↓
git checkout main(mainブランチに移動)
↓
git pull origin master(masterの最新をカレントブランチにマージ)

### 補足
自分は今回こんなやり方でしてしまったが、適用したstashの状態を取り消すコマンドもあるみたい

##### 補足参考文献
- http://transitive.info/article/git/command/stash/
PagerDuty で利用される電話番号を連絡先に登録する


## はじめに

Qiita では PagerDuty が導入されており、アラート発生時等はすぐ対応を行えるような体制を作っています
最近 PagerDuty からかかってくる電話番号の一覧がほしいとリクエストを頂いたのでこの記事を書きました

## PagerDuty で利用される電話番号

PagerDuty が電話の発信、SMS の送信を行う電話番号は通知先の番号に応じて最適な電話番号が使われます
そのため、過去かかってきた番号を連絡先などに登録しても、その番号で電話や SMS が送信されるとは限りません

そのため、 PagerDuty の サポートページから vCard をダウンロードできるようになっています
vCard については以下 URL から確認してみてください

https://support.mozilla.org/ja/kb/how-use-virtual-card-vcard

### PagerDuty の アプリから

PagerDuty は iOS, Android 用のモバイルアプリを提供しています。

https://support.pagerduty.com/docs/mobile-app

iOS, Android ともに、`〓` から ナビゲーションを開き、 Settings (設定ページ) に遷移
"Automatic Contact Card Management" をクリックすると 連絡先が登録されます
また、登録済みであれば、電話番号等が更新されます

### vCard をダウンロードする

PagerDuty の アプリを利用していない場合は、以下 URL から vCard をダウンロードすることができます

https://support.pagerduty.com/docs/notification-phone-numbers#update-the-vcard-via-web-download

## Reference

https://support.pagerduty.com/docs/notification-phone-numbers

https://support.mozilla.org/ja/kb/how-use-virtual-card-vcard

https://play.google.com/store/apps/details?id=com.pagerduty.android

https://apps.apple.com/us/app/pagerduty/id594039512
LinuxPCで自分のグローバルIPアドレスを取得する

タイトルの通り。自分の備忘記録として。調べてみるといくつか方法があるみたいなので、使いやすいのを記録しておこうと思った次第。

#### curlを使う
ターミナルで以下のどれかを実行する。
~~~
$curl ifconfig.io
~~~
~~~
$curl ifconfig.me
~~~
~~~
$curl globalip.me
~~~
Node.jsを用いて1分でWebサーバをローカルに立てる方法

開発環境
OS：Windows系
node.jsがインストール済み前提

やること
1.winowsキー＋Rの検索窓でcmdを入力し、cmd起動
2.cdでウェブサイトのファイルを置きたい場所に移動

:::note info
カレントディレクトリにファイルが作成されてしまうので、注意
:::

3.以下を投入
```ruby:cmd
>npx express-generator myExpressApp --view ejs
>cd myExpressApp && npm install
>npm start
```
AWSのルートユーザでどうしてもログインできない時に試したこと


## 目次

- [概要](#概要)
- [試したこと](#試したこと)
  - [ルートユーザのパスワードを変更する](#ルートユーザのパスワードを変更する)
  - [MFAの再同期を実行する](#mfaの再同期を実行する)
  - [拡張機能が入っていないブラウザで試す](#拡張機能が入っていないブラウザで試す)
- [まとめ](#まとめ)

## 概要

何度ルートユーザでログインを試みても、以下の画面のように認証に失敗したので、その際に試したことを記載します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/882682/50cf08fe-3c0b-d8de-3213-86464f79885a.png)

## 試したこと

### ルートユーザのパスワードを変更する
念のためパスワードを変更しましたが、結果は変わらずでした。

### MFAの再同期を実行する
MFAのトラブルシューティングから、MFAの再同期を行いました。

![MFA.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/882682/23d70731-101f-fc10-23e8-cf5895610eef.png)

しかし、以下添付のようになぜかエラーが発生しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/882682/4e0b27aa-20d4-bca9-ae4a-7f75fe6bbbff.png)

### 拡張機能が入っていないブラウザで試す

ブラウザはGoogle Chromeを使用していますが広告をブロックする拡張機能等を入れています。
これが悪さをしているのではないかと思い、シークレットモードで起動してログインを試しました。
結果として、これによりログインに成功しました。

## まとめ

上記より、以下あたりが試す価値がある気がします。

- MFAの再同期を実行する
- 拡張機能が入っていないブラウザで試す

同じように悩んでいる方がいれば、ぜひ試してみていただければと思います。
Chrome devtoolsのネットワークパネルでShiftキーを押しながらリクエストを見ると、リクエストの依存関係を見ることができる

Shiftキーを押しながらネットワークパネルのリソースの上にマウスを移動すると、どのリソースがどの別のリソースをロードしたかがわかります。

- 緑：呼び出し元
- 赤：リソースから呼び出している別リソース

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184922/8bcce2c9-1404-9a33-3592-8ba6aeac2819.png)
DrawProcedualで1マテでスキニングモデルの一括描画テスト

# 環境
Unity2021.2.18f1
burst1.6.5
jobs0.50.0-preview.8

# 概要
DrawProcedualの実験です。
多数のスキニングモデルを1マテリアルで一括描画してみるテストです。

AnimationInstancingのように1つのモデルを大量に出すのではなく、複数種類のモデルをたくさん出す為のテストです。

![](https://cdn-ak.f.st-hatena.com/images/fotolife/k/kenken5050/20220615/20220615204844.png)

面倒だったので使用するスキニングモデルは1スキンモデルのみにしています。

アニメーション毎にボーン行列をGraphicsBufferに保存して、シェーダでスキニング処理をしています。

テクスチャはTexture2DArrayに纏めています。（モデルのテクスチャはベーステクスチャのみで全部同じサイズ）

また、無駄にComputeShaderやJobSystemを使用しています。

左上の数値はFPSです。オブジェクトは全部で1000体出しています。

※モデルはオプティマイズオプションを無効にしないと実機でちゃんと表示されませんでした。
# コード
[ここ](https://kenken5050.hatenablog.com/entry/2022/06/15/211653)に全コード記載しています。
【Unity】UnityHubから旧バージョンのApple silicon対応Unityエディタをインストールする【Unity Hub】

## はじめに

　M1ProのMacBookProやM2のMacBookAirのユーザーが、UnityHubで旧バージョンのUnityエディタをインストールしなければいけない状況に置かれることがあります。

　実例として、VRSNSサービスであるclusterのワールドをアップロードする際、2022年7月18日から2021.3.4f1で作成する必要があり、MacBuildSupport、WindowsBuildSupport、AndroidBuildSupport、iOSBuildSupportの4つのモジュールをインストールする必要もあります。

　~~しかし、UnityHubは最新バージョンのエディタしかインストールすることができず、またUnity公式のダウンロードアーカイブを経由してUnityHubでインストールしようとするとIntel版を薦められます。そして同じダウンロードアーカイブから直接UnityインストーラーやUnityEditor（Apple silicon）をインストールして後ほどUnityHubに追加しても、モジュールの追加ができず、UnityエディタのBuildSettingsからプラットフォームを追加しようとしてもWindowsのモジュールが追加できません。インストーラ経由でモジュールを追加した場合、UnityHubから起動するとモジュールが認識されなくなりワールドのアップロードができません。~~

:::note
UnityHub 3.4.0より、旧バージョンのAppleシリコン対応Unityエディタを直接インストールすることができるようになりました！
:::
## UnityHubから旧バージョンのApple silicon対応Unityエディタを直接インストールすることはできないのか！？

:::note warn
~~2022年7月16日時点で、UnityHubから旧バージョンのAppleシリコン対応Unityエディタを直接インストールすることはできません。~~
:::
　~~けれども「旧バージョン」「Apple sillicon対応のエディタ」「UnityHub経由でモジュールを追加できる」は、手間がかかりますが可能です。~~
### 方法
1. [ダウンロードアーカイブ](https://unity3d.com/jp/get-unity/download/archive)からインストールしたいバージョンを選び、UnityHubのボタンを押してIntel版のUnityエディタをインストールする
1. 同じくダウンロードアーカイブから「ダウンロード（Mac）」より「Unity Ediror（Apple silicon）」をインストールする。
1. FinderでIntel版のUnityエディタとUnityBugReporterを削除し、別のディレクトリにインストールされたApple silicon版のUnityとUnityBugReporterをコピーする
1. [UnityHubを再インストール](https://unity3d.com/jp/get-unity/download)する

　これであたかもUnityHubから旧バージョンのApple silicon対応Unityエディタをインストールしたかのようになり、後ほどモジュールの追加も行うことが可能になります。

### 参考

https://forum.unity.com/threads/how-to-download-an-older-apple-silicon-patch-release-with-android-module.1227108/
Docker Networkを新規に作成して稼働中のコンテナを接続する


# やりたいこと

Docker Networkを新規に作成し、稼働中のコンテナを接続する。


# 手順

### 1.Docker Netowkrを作る

```shell
docker network create -d bridge --subnet=172.18.10.0/24 --gateway=172.18.10.1 net01
```


### 2.稼働中のコンテナを接続する

```shell
docker network connect net01 sshgitcont01
docker network connect net01 picobuild01
docker network connect net01 sambacont01
```


### 3.デフォルトのネットワークから切り離す

```shell
docker network disconnect bridge sshgitcont01
docker network disconnect bridge picobuild01
docker network disconnect bridge sambacont01
```