OmniAICreator/Qiita-1.07M huggingface dataset:
2021年9月にROS2をWindows10にインストールする

![SS 192.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565043/a41cd967-f549-8677-1efa-2e99bf69518d.png) 近道があった。でも賞味期限短いかも。今が旬。

#やること
Windows10にROS2をインストールします。ただそれだけのことですがちょっと沼りました。
自分の環境に限った方法かもしれませんが一応動きましたので、次に同じ道を通る方のために2021年9月現在の近道としてメモしておきます。
バージョンなどの変更でまた一筋縄ではいかなくなるかもしれないので、未導入の方はこの機会にぜひ。

#ポイント
- python3.7系をROS2が求める場所にインストールする
- (Alternative) ROS 2 Build Installation from aka.ms/ros を利用する
- foxyが入ります

#参考
[Installing ROS 2 on Windows](https://docs.ros.org/en/foxy/Installation/Windows-Install-Binary.html)
[ROS2.0をWindows10にインストールする](https://qiita.com/matryorobotics/items/beab21d4cf3199b1f6ff)
こちらの記事を参考にさせていただきました。ありがとうございました。

#必要なもの
- windows10のPC(今回の例では64bit版)

# STEP1 : pythonをよい感じにインストールする

#### ▼python3.7のダウンロード
以下のpythonの公式サイトより**Python 3.7.9 - Aug. 17, 2020**の、**Windows x86-64 executable installer**をDLします。
https://www.python.org/downloads/windows/
ダウンロードフォルダにインストーラーの**python-3.7.9-amd64.exe**が現れるので開きます。

#### ▼python3.7のインストールタイプの設定

インストール画面の下のチェックボックス２つにチェックをいれます。
□ Install Launcher for all users(recommended)
□ Add Python 3.7 to PATH

今回はpython3.7のインストール場所を設定したいので、
**Customize installation** をクリックします。


#### ▼python3.7のインストール場所の設定

次の画面の下の方にインストール場所を設定できるテキストボックスが出るので、図のように「C:\Python37」と記入します。
このディレクトリを設定することで、次の方法でインストールするROS2がpythonを判断できるようになります。
![スクリーンショット 2021-09-22 183904.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565043/7ffd6d63-1801-7d93-2dcb-3cdf56ae47bd.png)

画面上半分のチェックボックスはすべてチェックでよいと思います。

# STEP2 : 環境変数を設定する
windows左下の検索ボックスに「システム環境変数の編集」と入力し、該当のコントロールパネルを開きます。
「詳細設定」タブの画面の下にある「環境変数」ボタンを押します。

現れた画面の下段が「システム環境変数」です。
Pathとなっているところを選んで「編集」ボタンを押します。
C:&yen;Python37&yen;Scripts&yen;
C:&yen;Python37&yen;
があることを確認して閉じます。
（ちなみに自分はここにあるほかのバージョンのpythonはパスを消去＆アンインストールしました）

# STEP3 : ROS2をインストールする

#### ▼ https://aka.ms/ros project の力をお借りする
https://docs.ros.org/en/dashing/Installation/Windows-Install-Binary.html
のサイトを見てそのままインストールすればよいわけですが、**大事なのはサイトの下の方にある(Alternative) ROS 2 Build Installation from aka.ms/ros**という方法を使うことです。
コマンドプロンプトを**管理者権限**で開いて、一行ずつ実行していけばOKです。
（うっかり**Uninstall**まで実行しないようにお気を付けください。それはアンインストールです。）


# STEP4 : ROS2のデモノードを試す

#### ▼1つめのROS2ターミナルを開く
コマンドプロンプトを管理者権限ではない通常の方法で開きます。

そしてそのコマンドプロンプトのウィンドウに対してROS2の起動設定を行います。

```
call C:\opt\ros\foxy\x64\local_setup.bat
```
と入力します。2021年9月の時点では「foxy」がインストールされるはずですが、このバージョンが変更になっている場合は差し替えれば動くかもしれません。
参考サイトの事例では一つ古い「dashing」になっています。

次に、同じコマンドプロンプトウィンドウに

```
ros2 run demo_nodes_cpp talker
```
と入力します。
talkerがPublishingを出力し、
```[INFO] [xxxxxxxxxx.xxxxxxxxx] [talker]: Publishing: 'Hello World: 1'```
といった文字が画面に流れ始めます。

#### ▼2つめのROS2ターミナルを開く
新しいコマンドプロンプトを管理者権限ではない通常の方法で開きます。

先ほどと同じくROS2の起動設定を行います。

```
call C:\opt\ros\foxy\x64\local_setup.bat
```

と入力します。

次に、同じコマンドプロンプトウィンドウに

```
ros2 run demo_nodes_py listener
```
と入力します。
listenerがtopicを受信し、
```[INFO] [xxxxxxxxxx.xxxxxxxxx][listener]: I heard: [Hello World: xx]```
といった文字が画面に流れ始めます。


# ほかのものが動くかどうかはこれから
ubuntuに切り替えずにwindowsのままROS2が動いてくれるなら、普段の作業の片手間にROS2を試せてとても便利ですよね。
ほかのROS2アプリケーションが簡単快適に動くかどうかはまだ試していません。

・・・とここまで書いてから、WSLでROSを動かした方がいいのではないかと気づきました。

以下はWSL2を使ってROS2を導入する方法です。

https://qiita.com/Ninagawa_Izumi/items/efffddf0969392fc0a50
【AWS】NAT GatewayをTerraformで書くと…

LINE bot RSS受信用 Terraform

```tf
## AWS Config ##
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = ">= 3.21.0"
    }
  }
}

variable "aws_region" {
  default = "ap-northeast-1"
}
variable "aws_profile" {
  # type = string
  default = "aws-demo"
}
provider "aws" {
  region  = var.aws_region
  profile = var.aws_profile
}

# Lambda設置用のVPCを設置
resource "aws_vpc" "lamda_vpc" {
  cidr_block           = "10.0.0.0/16"
  instance_tenancy     = "default"
  enable_dns_support   = "true"
  enable_dns_hostnames = "true"
  tags = {
    Name = "Lamda on VPC"
  }
}

# サブネットを作成
## パブリックサブネットの作成
resource "aws_subnet" "PublicSubnet" {
  vpc_id            = aws_vpc.lamda_vpc.id
  cidr_block        = "10.0.1.0/24"
  availability_zone = "ap-northeast-1a"

  tags = {
    Name = "PublicSubnet"
  }
}

## プライベートサブネットの作成
resource "aws_subnet" "PrivateSubnet" {
  vpc_id            = aws_vpc.lamda_vpc.id
  cidr_block        = "10.0.2.0/24"
  availability_zone = "ap-northeast-1a"

  tags = {
    Name = "PrivateSubnet"
  }
}

# ルートテーブルを構築
##ルートテーブルの追加(0.0.0.0/0)
resource "aws_route_table" "public_subnet_route" {
  vpc_id = aws_vpc.lamda_vpc.id

  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.lambda_gateway.id
  }
}

##ルートテーブルの追加(1a)
resource "aws_route_table_association" "public_route_table" {
  subnet_id      = aws_subnet.PublicSubnet.id
  route_table_id = aws_route_table.public_subnet_route.id
}

# InternetGatewayの設定
resource "aws_internet_gateway" "lambda_gateway" {
  vpc_id = aws_vpc.lamda_vpc.id
}

# EIPを作成
resource "aws_eip" "nat_gateway" {
  vpc = true
}

# NAT Gatewayを構築
resource "aws_nat_gateway" "private" {
  allocation_id = aws_eip.nat_gateway.id
  subnet_id     = aws_subnet.PublicSubnet.id

  tags = {
    Name = "example_nat_gateway"
  }
}

# セキュリティグループの設定
resource "aws_security_group" "vpc_access" {
  name        = "vpc_access"
  description = "vpc_access"
  vpc_id      = aws_vpc.lamda_vpc.id

  ingress {
    from_port   = 443
    to_port     = 443
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  egress {
    from_port        = 0
    to_port          = 0
    protocol         = "-1"
    ipv6_cidr_blocks = ["::/0"]
  }

  tags = {
    Name = "lambda_access"
  }
}

# パブリックIPアドレスを見てみる
output "nat_gateway_public_ip" {
  value = aws_eip.nat_gateway.public_ip
}

# プライベートIPアドレスを見てみる
output "nat_gateway_private_ip" {
  value = aws_eip.nat_gateway.private_ip
}

```
FTPのファイル転送モードはバイナリ固定がおすすめ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94360/023e752c-1586-02c0-ab7d-b931f231e989.png)

FTPのテキストファイル転送モード設定について。FileZillaの場合、デフォルトで上記のようになっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94360/2d757b62-1057-938d-63a9-3b860bd2f4c8.png)

上記のように変更することをおすすめします。これにより、テキストファイルの改行コードを変換せずそのままダウンロードできるようになります。

**改行コードが変換されると困るケース**

Gitでクローンしたファイルとサーバからダウンロードしたファイルをdiffツールなどで見比べる時、「全ての行で差異あり」と判定されることがあります。

**これは何のための設定？**

昔、Windowsではテキストファイルの改行コードは `cr`+`lf`の組み合わせがお約束でした。これ以外の改行コードを用いるテキストファイルをコマンドラインやメモ帳で開くと、改行がない状態でテキストが表示されていました。

そのような問題を防ぐため、他のOSで作成されたテキストファイルをFTPで転送する際に改行コードを自動的に変換する機能が多くのFTPクライアントに備わりました。でも現在は、`cr`+`lf`じゃないと使えないような開発ツールはほとんどありません。

そんなわけで、何年も前に不要になっているのになかなか `cr`+`lf` が開発の現場から消えません。サーバにアップロードするとちゃんとlfに戻っているので、「なんで自分の環境だけこうなるの？」と悩んでいる人は多いと思います。

**注意**

ダウンロードの時はいいですが、アップロードの時は注意。もしお使いのエディタが `cr`+`lf`で保存する設定になっていたら、そのままアップロードされます。なのでエディタの設定も注意が必要です。

https://qiita.com/search?q=editorconfig+lf
エディタの場合はこれを。

Gitなども自動的に`cr`+`lf`に変換する設定になっていることがあります。

https://qiita.com/search?sort=&q=.gitattributes+lf
Gitの場合はこちら。

Windowsは罠が多い。周囲の開発者はほとんどMacユーザです。開発業界に関しては今はWindowsがMacに追随しています。

なんか、「テキストファイルの改行コードはlfで統一しよう」みたいなタイトルの記事にしたほうがよかったかもですね。
Raspberry Pi 初回起動時の流れ

【1960年生まれのおじさん日記】
 &emsp;60歳の定年退職後に再就職した現在の職場で ≪STM32(32bit汎用マイコン)≫でプログラム作成を
 &emsp;依頼され その後もRaspberry Pi でブロックチェーンを構築してと言われ 分からないことだらけ！
 &emsp;一応は、若いころから 製造業で働き 制御用ソフト や アプリケーションの作成をしたこともある
 &emsp;けれども・・・

 &emsp;この年齢になって Raspberry Pi でブロックチェーンの構築などするとは思わなかったおじさんの
 &emsp;メモ書き記録。間違いも多々あるかと思いますが、お許しください。

---
**はじめに**
Raspberry Pi4 の初回起動時の流れを簡単に記述

---

Step1：モニター(HDMI接続) / マウス(USB) / キーボード(USB) を Raspberry Pi4 本体に接続する。
&emsp;&emsp;&emsp;&emsp;USB Type C を本体に挿入と同時に Raspberry Pi4 は、Power On となる

Step2：電源投入後の最初の Welcome 画面 で ＜Next＞ を選択
![P1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2056854/0f153e1a-c2de-ebaf-bca7-1f5766d2acca.jpeg)

Step3：Country/Language/TimeZoneの設定画面で それぞれの設定を行い ＜Next＞ を選択
![P2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2056854/a66506ef-353d-65c7-3c01-cfb05585e5d4.jpeg)

Step4：Password の設定画面では、Password を入力して ＜Next＞ を選択
&emsp;&emsp;&emsp;★ Password は、外部からのリモート接続時に必要な様だ!
![P3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2056854/ed2833f2-943b-f267-594e-a3771ace4410.jpeg)

Step5：画面確認の表示では、画面に問題がなければ <Next> を選択
![P4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2056854/cdc1f007-4baf-0113-78bc-59491970ef18.jpeg)

Step6：WiFi設定画面では、接続する WiFi を選び <Next> 接続のための パスワードを入力して ＜Next＞ を選択
![P5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2056854/c41f1574-4538-e149-ab36-2e281347916e.jpeg)
![P6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2056854/a6aa4239-b2ad-548e-3005-3db90b42ea8b.png)


Step7：Update Software の画面で ＜Next＞ を選択する。
&emsp;&emsp;&emsp;★Update するのに 約20分必要だった。
![P7.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2056854/023cf111-816f-9776-ace0-eff286399fec.jpeg)

Step8：Update 終了後に 再起動画面の確認画面が出るので 再起動を行う。
&emsp;&emsp;&emsp;★再起動後 日本語表示で Raspberry Pi が起動される。
![P8.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2056854/8fb34438-45a8-0989-cdcf-2d232309230e.jpeg)

Step9：再起動後に ターミナルウィンドウ に入り 以下のコマンドを実行
&emsp;&emsp;&emsp;★Raspberry Pi4 のツールを更新してくれる。
&emsp;&emsp;&emsp;★Step7 との違いは、何だろう・・・？

```
$ sudo apt-get update
$ sudo apt-get upgrade
```
※日本語入力システム(mozc)は、Raspberry pi OS image にインストールされていた(2022年9月5日 確認)
Step10：Googleが開発した日本語入力システムを下記コマンドでインストール

```
$ sudo apt-get install ibus-mozc
```

---
☆2021年9月22日(水) 午後7時50分 初版 (Ver1.00) 作成
☆2021年9月23日(木) 午後0時52分 Ver1.10 - Step9 & Step10 を追加
☆2021年9月27日(月) 午後3時00分 Ver1.11 - 必要な各ステップに 画面イメージを追加
☆2021年9月28日(火) 午後1時40分 Ver1.12 - 文言を変更

---
参考：
[Raspberry Pi OS イメージの作成方法](https://qiita.com/ytetsuo/items/7f0e682785280888fc1d "Raspberry Pi OS")

---
JavaScriptの0

JavaScriptにおいて0は「false」と判定される。0の存在を忘れて真偽値判定していると知らぬ間に0をfalse側にぶち込んでいることがある。

```
let a = 1;
function fn(num) {
    num = num || -1; //←右辺のnumにundefineもnullもNaNも0も入る
    console.log(num);
}
fn(a);
```

引数をデフォルト引数```num=1```にすればいいだろうと思ったけれど、0はよくとも```null```などの場合にはデフォルト引数がセットされず、nullがセットされてしまうらしい。なぜ……
（num自体をif文判定してデフォルトの値を引数にセットする記述を追加する必要がある）

0をfalse判定されるとまずいことにならないかどうか、プログラム上で気にかけておく必要がある……がうっかり忘れそうなので、真偽値判定にかける値に0を含めないようにするか、``` === 0```など直に判定を記述した方がいいかもしれない。
CSIRT とは

## 勉強前イメージ

それぞれセキュリティの調査してるときに出てきたけどわからなかった

## 調査

### CSIRT とは

Computer Security Incident Response Team の略で、シーサート と読みます。
セキュリティインシデントに関する報告を受け取って、調査・対応を行うチームのことを指します。

1988年にネットワークに甚大な被害を与えたことから、インシデント対応と情報共有を担う組織として
CSIRTが米カーネギーメロン大学内に設置されたのが始まりで、その後世界各国で作られるようになた。
日本ではJPCERT/CCという組織が1996年に発足しました。
イメージとしては、CSIRTという組織がどこかに存在する というより
セキュリティインシデントの調査・対応を行うチーム というイメージで社内・組織内で発足することがあります。

### CSIRT の種類

CSIRTにもいくつか種類があって、6つに分類されます。

- National CSIRT

国・地域が関わるインシデントに対応するCSIRTで、国や地域との窓口として活動します。
政府機関や企業との連携を行います。

- Internal CSIRT

組織や顧客が関わるインシデントに対応するCSIRTで、
Internal CSIRTの多くが企業内で社員・顧客に対して活動を行います。

- Analysis Center

新しい脆弱性や攻撃手法を調査するCSIRTで、
サイバー攻撃の分析や解析を行い、注意や呼びかけを行います。

- Coordination Center

発生したインシデントの火消しを行うCSIRTで、
政府・企業間など複数のCSIRT間の情報共有を行うCSIRTです。

- Vendor Team

自社製品の脆弱性に対応するCSIRTで、
新しいセキュリティホールなどの報告を受けた際、検証・更新プログラムの作成や注意喚起を行います。

- Incident Response Provider

契約に応じて外部組織のインシデント対応を代行するCSIRTで、
組織内CSIRTを有償で代行する業者を指します。

### CSIRTの仕事内容

#### 平常時の仕事内容

平常時は社内各部署や情報連携、インシデント情報収集などを行います。

- 経営部門や社内各部門との連絡・連携
- セキュリティ製品・サービスの選定・導入・運用
- 社内のセキュリティ教育研修実施
- 各種脅威の情報収集

#### インシデント発生時の仕事内容

インシデント発生時は、インシデントの把握・原因分析・経営層への報告や
問題解決や再発防止策の策定などを行います。

- インシデント発生の検知・報告
- インシデントの影響範囲や原因の調査
- 社内外の報告
- 再発防止対策の実施

## 勉強後イメージ

CSIRTって初めて聞いた。
最初調べたときにそういう組織があるって思ったけど
そうじゃなくてそういうチームを作る的なやつか・・・
あといろんな分類のCSIRTがあるんですね

## 参考

- [CSIRTとは？ その役割や体制、SOCとの違い](https://tokiocyberport.tokiomarine-nichido.co.jp/cybersecurity/s/column-detail80)
- [CSIRTとは、インシデントに対応する組織。その役割と導入プロセスについて](https://www.amiya.co.jp/column/csirt_20200720.html)
ルーティングについて勉強しなおそう

#ルーティングとは
受け取ったリクエストを認識し、適切なコントローラ内のアクションの実行をするもの。

```ruby
HTTPメソッド 'パス', to: 'コントローラ名＃アクション名'
```
上記のような書き方でroutes.rb内に記述していく。

###凡例

```ruby
#ルーティングの記述
get '/samples/:id', to: 'samples#show'

#HTTPリクエスト
Get /samples/21
```
上記のようにルーティングされ、HTTPメソッドが送られてきたとする。このリクエストはsamplesコントローラのshowアクションに割り当てられて、paramsには{ id: '21' }というハッシュが含まれている。
mysqlで4bytes 絵文字が含まれているか検索する

tableのcharacter set を utf8mb4 にしておくことで、4bytes 絵文字をテーブルに格納することができます。
実際に運用し始めた後に、そういった絵文字が入っているのか？が気になったときに調べる方法です。

# 結論

```sql
select * from test  where hex(w) regexp '^(..)*(F0)'; 
```

でチェックできます。

# 試してみる

- dockerでmysqlを立ち上げる

```bash
docker run --rm -e MYSQL_ROOT_PASSWORD=a -e MYSQL_DATABASE=test -p 3306:3306 mysql:5.7  
```

- コンソールからアクセス

```bash
mysql -u root -pa -h 127.0.0.1  test
```

- 文字コードを変更

```sql
set character_set_client="utf8mb4";
set character_set_connection="utf8mb4";
set character_set_database="utf8mb4";
set character_set_results="utf8mb4";
set character_set_server="utf8mb4";
```

- テストデータを作成

```sql
create table test (
  w text
) charset=utf8mb4;


insert into test values
("alpha"),
("日本語"),
("⛩"),
("これは3byte⛩"),
("⛩なので引っかからないのが正しいです"),
("😀"),
("これは4byte😀"),
("😀なので引っかかるのが正しいです"),
;
```

- テスト！

```sql
mysql> select * from test  where hex(w) regexp '^(..)*(F0)';
+---------------------------------------------------+
| w                                                 |
+---------------------------------------------------+
| 😀                                                  |
| これは4byte😀                                       |
| 😀なので引っかかるのが正しいです                    |
+---------------------------------------------------+
3 rows in set (0.00 sec)
```

無事絵文字が含まれた文字列を検索できました。
CCNA　ルーティング

今回はルーティングについて書いていきます。

まずはルーティングの流れについて確認していきます。

① 非カプセルを行い、パケット情報を取り出します。
② ルーティングテーブルからネットワーク部が完全に一致しているエントリがあるか確認する
③ IPパケットをカプセル化する。
④ ネクストホップと出力インターフェイスに従ってパケットを転送する。
この時、宛先MACアドレスはARPテーブルを確認しますが、
情報が無ければ、ARP要求を送信して問い合わせます。
基本的に宛先IPアドレスと送信IPアドレスは変わらないが、
宛先MACアドレスと送信元MACアドレスはルーターを経由する度に変わる。

**CEF**

CEF(Cisco Express Forwarding)はルーティングの検索処理を
簡素化する作業のことを言います。
本来はパケット情報のIPアドレスをルーティングテーブルで確認して、
ARPテーブルでMACテーブルを確認すると言った検索作業を
2回行っています。
しかし、この検索をより早くするためにルーティングテーブルから
FIB(Forwarding Information Base)を、ARPテーブルから
隣接テーブルを作成します。こうすることで、
確認する点を1度にしています。

**一致しているエントリが無い場合**

もし、ルーティングテーブルに宛先の経路情報が無い場合、
ルーターはパケットを破棄します。
そして、送信元に　ICMPで宛先経路到達不可のタイプ3コード1を送ります。

**ロンゲストマッチ**

ルーティングテーブルで複数のルート(エントリ)が検出された場合。
ネットワークアドレスのビットが最も長く一致しているルートに転送します。
これをロンゲストマッチと言います。これは第四オクテットまでを
2進数にします。

**デフォルトルート**

先程の記述で、ルーティングテーブルに宛先の経路情報が
なかった時、パケットを破棄すると書きました。
では、全ての経路情報を書かないといけないのかと言うとそうではありません。
その場合のルートを設定することができます。それをデフォルトルートと言います。
これを設定すると宛先の経路情報がなくてもパケットは破棄されない。
また、登録する経路情報が少なくていいのでCPUの負担が軽減される。
しかし、これは最終手段としましょう。これをラストリゾートゲートウェイと言います。
基本的に宛先が分からないルートはISPに飛ばし、
社内ネットワーク以外はデフォルトルートで社外に飛ばすのが一般的です。

宛先が無い場合のIPアドレスは0.0.0.0を入力するようにして下さい。

**スタティックルーティング**

ルータは直接接続されているネットワークへのルートは自動で登録されます。
しかし、直接繋がっていないネットワークは手動か自動で登録が必要です。
登録されたルート情報は変わらないので、CPUの負荷は小さくなる。

**ダイナミックルーティング**

スタティックルーティングは手動だが、ダイナミックルーティングは自動です。
また、スタティックルーティングは障害が発生しても手動で切り替えるまで
指定方向にデータが転送され続けます。
しかし、ダイナミックだと自動でルートが切り替わります。
それをルーティングプロトコルで設定します。
しかし、スタティックよりもCPUに負荷がかかります。

**ルーティングプロトコル①**

ルーティングプロトコルにもいくつか種類があります。
経路までの距離をメトリックと言い、これを使って設定します。
RIP(Routing Information Protocol)は経由するルータの数(ホップ数)を
メトリックにしています。
OSPF(Open Shortest Path First)は帯域幅をメトリックにしています。
他にEIGRP(Enhanced Interior Gateway Routing Protocol)、
BGP(Border Gateway Protocol)、
IS-IS(Intermediate System to Intermediate System)などがあります。
都度確認していきましょう。

**AD値**

複数のルーティングプロトコルを設定している時、
どれが優先されるのかが決められる値があります。
それをAD値と言います。アドミニストレーティブディスタン値の略です。
これは予めルーティングプロトコルにAD値が設定されています。
その低い値が優先度が高いとなります。スタティックルートは初期が1ですが、
それは設定することができます。それをフローティングスタティックルートと言います。

**ルーティングプロトコル②**

インターネットは各組織(AS:Autonomus System)によって管理されています。
このAS同士を繋ぐ、EGP(Exterior Gateway Protocol)や
ASの内部のIGP(Interior Gateway Protocol)があります。

では、アルゴリズムによって分類していきましょう。
これは何が最適経路なのかと言う考え方です。
1つ目はバスベクタ型です。これはベストパス選択アルゴリズムによって最適経路を
導きます。経由するASが少ない経路をベストパスとしています。
BGPがこれにあたります。

2つ目はディスタンスベクタ型です。
これはルーティングテーブルの情報を交換し合います。そしてディスタンスとベクトルを基に
ベルマンフォード法によって最適経路を計算します。
これはコンバージェンス(ルート情報が行き渡るまで)は遅く、ルータへの負荷も小さい。
RIPがこれにあたります。しかし、EIGRPは3つ目のリンクステート型の特徴も
取り入れているので、拡張ディスタンスベクタ型と言われて、アルゴリズムはDUALです。
これはコンバージェンスは早く、ルータの負荷もリンクステートより小さい。

3つ目はリンクステート型です。
これはルータのインターフェイスがどのルータと隣接しているかという接続情報を
交換し合います。SPFアルゴリズムで最適経路を計算します。
OSPFやIS-ISがこれにあたります。
コンバージェンスは早いや、ルータへの負荷が大きいです。

最後にこれらのルーティングプロトコルは2つに分かれます。
クラスフルルーティングプロトコルとクラスレスです。
これはサブネットマスクを含むことができるかどうか、つまり
細かな設定をできるかどうかで分けています。
クラスフルはRIPのバージョン1のみです。

**ルート集約**

複数のルートをまとめることをルート集約と言います。
これによりメモリの消費を抑えたり、ルーティングテーブルの検索の負荷を軽減させたり、
ルーティングアップデートのトラフィックを軽減できる。
しかし、RIPのバージョン1は手動集約できず、OSPFは自動ができない点もある。
自動集約の時はクラスを意識して、集約するが、不連続サブネットだと
自動集約ができなくなる。
Amazon SageMaker ノートブックインスタンスの地味だけど便利な機能

# はじめに

Amazon SageMaker を使うと、自分のマシンの環境を汚さずに機械学習に関するあれこれを試せるので便利です。今回は、Amazon SageMaker のノートブックインスタンスのちょっとした機能をご紹介します。

# まずはノートブックインスタンスの起動

ノートブックを起動しなければ話は始まりません。しかし、ノートブックの設定にも隠れた便利機能があるのです。

まずは AWS コンソールから SageMaker のコンソールに移動します。

![スクリーンショット 2021-09-22 18.23.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315319/1f4956c1-f9d8-41a7-c2f9-453f010a8ae8.png)

## ライフサイクル設定

SageMaker のコンソールの左側のメニューから「ノートブック」をクリックして展開します。はい、ここで「ライフサイクル設定」が表示されました。

![スクリーンショット 2021-09-22 18.25.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315319/a69e907c-2b04-1fe8-c73e-45c090b22f3e.png)

ライフサイクル設定とは、ノートブックインスタンス起動時に実行するスクリプトを定義するための機能で、[こちらでサンプルがたくさん公開](https://github.com/aws-samples/amazon-sagemaker-notebook-instance-lifecycle-config-samples) されています。サンプルの中には、たとえばノートブックインスタンスが使用されずアイドル状態が続いたら自動的にシャットダウンするものがあります。お財布に優しくて便利！

ライフサイクル設定は、メニューの「ライフサイクル設定」をクリックしてからオレンジ色の「設定の作成」をクリックすれば作成できます。作成したライフサイクル設定は、ノートブックインスタンスの設定の際に指定します。

## ノートブックインスタンスの作成

左側のメニューで「ノートブックインスタンス」をクリックしてからオレンジ色の「ノートブックインスタンスの作成」をクリックします。

するとノートブックインスタンスの設定画面になります。最小構成としては以下の設定をしてから一番下にあるオレンジ色の「ノートブックインスタンスの作成」をクリックすれば OK です。

```python
"ノートブックインスタンス名"：任意の名前（英数字とハイフンを使用可能）
"IAMロール"：「新しいロールの作成」をクリックし、オレンジ色の「ロールの作成」をクリック
```

でもちょっと待ってください！隠れているメニューを開いてみると、地味に便利な機能があるのです。

一番上の「ノートブックインスタンス設定」の一番下に「追加設定」と書かれた部分があるはずです。そこをクリックしてみると、ライフサイクル設定とボリュームサイズの設定ができます。

![スクリーンショット 2021-09-22 18.52.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315319/de7f219b-4fda-11ca-f0cc-169ed1374fbf.png)

ライフサイクル設定は言わずもがな、先ほどご紹介した機能ですが、ここで予め作成しておいたライフサイクル設定を選択することができますし、ここから新規にライフサイクル設定を作成することもできます。

ボリュームサイズは、ノートブックインスタンスにアタッチされるストレージのサイズで、初期値は 5GB です。大量のデータの前処理をするなどたくさんストレージ容量が必要なことをする場合は、ノートブックインスタンスの設定時にボリュームサイズを大きくしておくと便利です。

ノートブックインスタンス設定画面を下までスクロールすると、「Git リポジトリ」と書かれた部分があります。ここをクリックしてみましょう。

![スクリーンショット 2021-09-22 18.53.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315319/82947e6f-ca01-0fd5-e803-72a5de7b7102.png)

「リポジトリ」のところで「このノートブックインスタンスのみに・・・」を選択し、「Git リポジトリの URL」のテキストボックスに GitHub のリポジトリの URL を入れておくと、ノートブックインスタンス起動時にリポジトリが Clone されます。すぐにリポジトリのソースコードをいじるところから始められるので便利です。

[こちらの GitHub リポジトリ](https://github.com/aws-samples/aws-ml-jp) に SageMaker の各種機能やそのほかのサービスとの連携方法などが解説されたサンプルノートブックが公開されているので、初めはこちらのリポジトリを設定しても良いかもしれません。

# ノートブックインスタンスが起動したら

ノートブックインスタンスの設定が終わって数分すると使用可能になります。ノートブックインスタンス一覧画面の右側にある「アクション」から「Jupyter を開く」などのリンクをクリックして Jupyter 環境を開きます。

Jupyter の画面では、設定時に Git リポジトリの URL を設定していた場合は初めからフォルダが表示されます。ここで、上にあるタブ（Files, Running, Clusters ...）から「SageMaker Examples」をクリックしてみましょう。

以下の図のように、公式の SageMaker サンプルノートブック（英語）が表示されます。検索性が非常に悪いですが、ノートブック名を頼りに興味があるノートブックを見つけて、右側にあるオレンジ色の「Use」をクリックすればサンプルノートブックをすぐに試せます。

![スクリーンショット 2021-09-22 19.11.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315319/47b361cc-8d5b-b3cb-bbcc-afaf73127b1d.png)

# ご注意

ノートブックインスタンスは起動している間課金され続けるので、不要になったら削除しましょう。ノートブックインスタンスを「停止」した場合、インスタンスに対する課金は停止しますが、インスタンスにアタッチされているストレージに対する課金は継続するので、不要になったら「停止」したのち「削除」まで実施してください。

# まとめ

Amazon SageMaker ノートブックインスタンスの地味に便利な機能をご紹介しました。地味すぎたかもしれませんが、どなたかのご参考になれば幸いです。
firebase-uiを使おうとしたら"firebase_app__WEBPACK_IMPORTED_MODULE_0__.default is undefined"といわれたときの対処法

# 問題
nuxtでfirebase-uiを使ってログイン機能を実装しようとしたら、
`"TypeError: firebase_app__WEBPACK_IMPORTED_MODULE_0__.default is undefined"`
といわれました。
#原因
firebase-uiのバージョン5.0と、firebaseのバージョン9.0の互換性がないことが原因でした。

```
npm install firebaseui@next
```
という形でfirebase-uiを再度インストールしたら治りました。
IBM Cloud Advocate v1 受験体験記

# IBM Cloud Advocate v1について
IBM Cloud Advocate v1は、2021年7月から提供を開始したIBM Cloudの初級レベルの認定試験です。
エンジニアだけではなく、営業やマネージメントなど、IBM Cloudに関わる全ての人を試験対象者としており、クラウド開発の経験がない方でも十分に合格が狙えます。

# IBM Cloud Advocate v1の試験概要

https://www.ibm.com/training/certification/C0010900

# 筆者の前提スペック
- IBM Cloudは普段の業務で使っているが、提供しているサービスについて、広くは理解していない（例えば、IaaS系のサービスや分析系のサービスなどは、あまり使ったことがないので、詳しく知らない）
- KubernetesやOpenshiftは普段からちょこちょこ使っている
- AWSやAzureの資格はいくつか保持しており、クラウドの基礎はわかっている（つもり）
    - AWS Certified Cloud Practitioner
    - AWS Certified Solutions Architect - Associate
    - Microsoft Certified: Azure Fundamentals
- 英語はあまり得意ではない


# 学習方法
基本的には、下記のラーニングパスに沿って学習をしていけば、問題なく合格できると思います。

https://www.ibm.com/training/path/ibmcloudadvocate

## Pre-Assessment
有料の模擬試験です。試験勉強前に腕試しも兼ねて受験したところ、無事に合格できました。試験終了後にスコアと合わせて、各出題分野における正答率が表示されるため、自分が理解できていない分野を把握するのにもちょうどよいのではないかと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134250/573190f9-44f0-3537-f021-4bbbd7dd7348.png)


## Introduction to Cloud
<img width="170" height="170" src="https://images.credly.com/size/340x340/images/b0607951-b6f7-47d0-af16-7112971ab2ef/Cloud_Core_-_Developer_Skills_Network_-_v3.png">
画像出典: https://www.credly.com/org/ibm/badge/cloud-core

クラウドとは何ぞや？といった本当にクラウドの基礎の部分について学習することができるE-Learningコンテンツです。内容をチラ見して、流石にこれくらいはわかってるかな…と判断したため、各章末のクイズにのみ取り組みました。

https://cognitiveclass.ai/courses/introduction-to-cloud

## IBM Cloud Essentials V3
<img width="170" height="170" src="https://images.credly.com/size/340x340/images/58e2cad5-5551-44a6-8285-06d6a4aa9cb3/IBM_Cloud_Essentials.png">
画像出典: https://www.credly.com/org/ibm/badge/ibm-cloud-essentials.2

IBM Cloudが提供している幅広いサービスについて学習することができるE-Learningコンテンツです。冒頭でも申し上げた通り、IBM Cloudを普段から利用しているものの、IBM Cloudが提供しているサービスについて、広くは理解していなかったため、自分が理解できていないと思った分野について重点的に取り組みました。

https://cognitiveclass.ai/courses/ibm-cloud-essentials


# 試験結果
テストセンターで受験し、無事に合格できました。
なお、オンラインではなく、テストセンターでの受験を選択したのは、受験申込時に日本語の試験監督が選択できず、「オンライン受験慣れてないし、トラブったらやだなぁ…」と思ったためだったのですが、記事執筆にあたって確認したところ、現在は日本語の試験監督も選択できるようになっていました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134250/f917a6da-dd90-191c-8881-1192fe2a1dbd.png)


# 参考文献
* IBM Cloudの新認定試験IBM Cloud Advocate v1を受けてみた

https://qiita.com/teruq/items/1bb67c516dd73c7a1ef8
iMac(2017)BootCamp環境でWindows11のアップグレード要件を満たせるか確認してみた

![windows11](https://c.s-microsoft.com/en-us/CMSImages/1399_Panel01_Hero_WindowsSV.jpg?version=7b8fd32d-ae59-c18a-c858-7f309b21ec98)

[Windows11公開(2021/10/05)](https://news.microsoft.com/ja-jp/features/20210901-windows-11-available-on-october-5/)に際して。
自身の利用PC(iMac 2017製)がアップグレードできるかどうか確認するとともに、以下の観点で探ってみました。

 - アップグレードするメリットはあるのか
 - Windows10はいつまでアップグレードせずに利用できるのか
 - PCを購入する必要があるのか


---

## ゴール
- Windows11が案件で必要となった場合に自分の環境がスムースに移行できるか確認する
    - 移行できない場合にPC購入の踏ん切りをつけることが本目的かも知れない :sweat_smile: 

## 結論
- Windows11へのアップグレードのメリットは不明のまま
- [2025年10月14日](https://docs.microsoft.com/ja-jp/lifecycle/products/windows-10-home-and-pro)まではWindows10が使える状態なので、直近で困ることはなさそう
- 私の環境下(iMac(2017)BootCamp利用)では、アップグレード要件を満たせませんでした
    - 別途PCの購入が必要なようです
    - 満たしていない要因：**プロセッサがサポートされていない**
    - 「iMac(2017)BootCamp利用下ではアップグレードできない」という下馬評通りの結果でした
    ![PC正常性チェック_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1866227/30e16588-9765-6e84-ca83-04df765def79.png)

> [Windows 11 でサポートされている Intel プロセッサ](https://docs.microsoft.com/ja-jp/windows-hardware/design/minimum/supported/windows-11-supported-intel-processors)

## [Windows 11 システム最小要件](https://www.microsoft.com/ja-jp/windows/windows-11-specifications)
項目|内容
:-|:-
プロセッサ|1 ギガヘルツ (GHz) 以上で 2 コア以上の64 ビット互換プロセッサまたは System on a Chip (SoC)
メモリ|4 GB RAM
ストレージ|64 GB 以上の記憶装置
システム|ファームウェア	UEFI、セキュア ブート対応
TPM|トラステッド プラットフォーム モジュール (TPM) バージョン 2.0
グラフィックス カード|DirectX 12 互換のグラフィックス / WDDM 2.x
ディスプレイ|9インチ以上、HD解像度 (720p)
インターネット接続|Windows 11 Home Edition のセットアップには Microsoft のアカウントとインターネット接続が必要です

## [PC 正常性チェック アプリ][heals_check_app]
[heals_check_app]: https://aka.ms/GetPCHealthCheckApp

- PC が要件を満たしているか、互換性を評価できます。

## Windows 11 って何ができるの？ Windows10と何が違うの？

> [新しい Windows 11 OS へのアップグレード | Microsoft](https://www.microsoft.com/ja-jp/windows/windows-11?OCID=pchc_windows_app_omc_win)

### デザインが変わる

- スタートメニューはアプリ配置になる
- タスクバーが下に固定化される
- オブジェクトの再配置がしやすくなる
    - 「Windows + 矢印」で行っていた配置がより直感的に再配置可能になる？
既存のサーバを Terraform で管理できるようにする

Terraform で既存の AWS リソースを管理できるようにします。

#Terraform で管理するリソースの確認

今回は以下の通り
- VPC
- subnet
- SecurityGroup
- Key Pair
- Elastic IP Address
- EC2

#下準備
IAM ユーザーのアクセスキーを設定し、リソースへアクセスできるようにした準備を行います。
まず direnv をインストールします、以下の記事が参考になります。

https://qiita.com/kompiro/items/5fc46089247a56243a62

direnv のインストールが完了したら、``.envrc``ファイルを作成します。

```go:.envrc
export AWS_ACCESS_KEY_ID = "{アクセスキーId}"
export AWS_SECRET_ACCESS_KEY="{シークレットアクセスキー}"
```

これで、``.envrc``以下の階層に入ると自動的に認証情報が適用されリソースへのアクセスが可能になります。

#テンプレートの作成
公式ページで各リソースの基本的なテンプレートを確認。

###例
**VPC**

```tf:VPC_BasicUsageWithTags
resource "aws_vpc" "main" {
  cidr_block       = "10.0.0.0/16"
  instance_tenancy = "default"

  tags = {
    Name = "main"
  }
}
```

https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc

**subnet**

```tf:subnet_BasicUsage
resource "aws_subnet" "main" {
  vpc_id     = aws_vpc.main.id
  cidr_block = "10.0.1.0/24"

  tags = {
    Name = "Main"
  }
}
```

https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/subnet

まず VPC のテンプレートを作成する。
ローカルで``vpc.tf``を作成し、先程のコードをコピー。

```tf:vpc.tf
resource "aws_vpc" "main" {
  cidr_block       = "10.0.0.0/16"
  instance_tenancy = "default"

  tags = {
    Name = "main"
  }
}
```

テンプレートファイルの先頭でリソースの種類の指定と、名付けを行っています。
``vpc.tf``と同じ階層で``terraform import``を実行。
テンプレートファイルで指定したリソースの種類と名前、読み込むリソースの ID を指定して実行します。

```
terraform-server % ls
vpc.tf
terraform-server % terraform import aws_vpc.main {VPC ID}
aws_security_group_name: Importing from ID "xxxxxxxxxxxxxxxxxxxx"...
aws_security_group_name: Import prepared!
  Prepared aws_security_group for import
aws_security_group_name: Refreshing state... [id=xxxxxxxxxxxxxxxxxxxx]

Import successful!

The resources that were imported are shown above. These resources are now in
your Terraform state and will henceforth be managed by Terraform.
```

続いて``terraform plan``を実行して現在の環境と``vpc.tf``の差分を確認します。
``vpc.tf``を編集し、``terraform plan``の実行結果が以下のようになったら次のリソースのテンプレート作成に移ります。

```
terraform-server % terraform plan
aws_vpc.main: Refreshing state... [id=vpc-xxxxxxxx]

No changes. Your infrastructure matches the configuration.

Terraform has compared your real infrastructure against your configuration and found no differences, so no changes are needed.
```

#参考資料

https://qiita.com/kompiro/items/5fc46089247a56243a62
vue.js css last-child 効かない

vue.jsでlast-childが効かないぞ？


結論

```hoge.vue

<style>

    .kudamono .kudamono-item {
        background-color: blue;
    }

    .kudamono .kudamono-item:last-child {
        background-color: red !important;
    }

</style>




<div class="kudamono">
    <div v-for="(v,key) in menu" class="kudamono-item">
        {{v.body}}
    </div>
</div>


```

これで効く。

* v-forの外側にclassを作る
* 上記でv-forのdivを囲い設定する

といった感じです
AWS MGNでサーバー移行の際にCloud-init導入の話

# はじめ

最近、職場で初めてMGNでサーバー移行を実施しました。運営が何年間も経ったサービスのサーバーは何が入っているのか全く分からないが、とりあえずオンプレ環境からAWS環境に移行したい…CloudEndureは当然できますが、もう少し最新のものを使いたいなーという気持ちで、MGNを採用しました。

# Cloud-init導入経緯
目的はサーバー初期設定を行いたいですが、当初にMGNの「高度な詳細」のユーザーデータにbashスクリプトを書けば良いと思いましたが、どうしてもスクリプトが実行されないっぽいです。AWSのドキュメントにもこの辺がかなり曖昧で、Cloud-init利用が必要のような雰囲気です。しかたがないので、Cloud-initエージェントをソースサーバーにインストールして、Cloud-init利用に至りました。

# どのように書くのか（最低限）

```
#cloud-config
ssh_pwauth: yes ← PWでSSHログイン許可
package_update: false ← ubuntuだとapt-get updateと同様
hostname: hoge
fqdn: hoge.excite.co.jp
manage_etc_hosts: localhost
locale: ja_JP.UTF-8
timezone: Asia/Tokyo
```

```
users:
  - name: sakamoto
    homedir: /home/sakamoto
    sudo: ["ALL=(ALL) NOPASSWD:ALL"] ← root権限
    shell: /bin/bash
    no_user_group: false ← 新しいグループ作成しない
    primary_group: hage ← 所属グループ指定
    id: '1001' ← uid指定できる
```

```
chpasswd:
  list: |
    sakamoto:s3cret ← 好きなPW指定
  expire: true ← これで初回ログインでPW変更強制
```

```
runcmd:
  - sed -i'' -e's/^server 180.xxx.xxx.xxx/server 169.yyy.yyy.yyy/' /etc/ssh/sshd_config
↑ファイルの中身を書き換えができる。基本的にUbuntuコマンドを普通にかける
```

最後に丸ごとファイル上書きもできます

```
write_files:
  - content: |
      # /etc/nsswitch.conf
      #
      # Example configuration of GNU Name Service Switch functionality.
      # If you have the `glibc-doc-reference' and `info' packages installed, try:
      # `info libc "Name Service Switch"' for information about this file.

      passwd:         compat systemd
      group:          compat systemd
      shadow:         compat
      gshadow:        files

      hosts:          files dns
      networks:       files

      protocols:      db files
      services:       db files
      ethers:         db files
      rpc:            db files

      netgroup:       nis
    owner: root:root
    path: /etc/nsswitch.conf
    permissions: '0755'
```

これをMGNのユーザーデータに登録すれば、サーバー移行の際に初期設定が行われます。
細かいドキュメントが[こちらの公式サイト](https://cloudinit.readthedocs.io/en/latest/topics/modules.html)にあります。
以上です。
Azure Remote Rendering Asset Tool で生成される config.json について

# はじめに
**Azure Remote Rendering** を PC ( Windows ) で検証するためのツール、**Azure Remote Rendering Asset Tool** ( ARRT )の config.json について調査した内容をまとめておきます。
Azure Remote Rendering Asset Tool は GitHub からダウンロードすることができ、3Dモデルの変換、Azure Remote Renderin の実行を行えるPC向けツールです。

今回、Azure Remote Rendering Asset Tool がバージョンアップされていたので、最新バージョンをダウンロードし、Azure Remote Rendering のアカウントID, キーを設定していたところ、
過去の登録情報と競合したのか、アプリが強制終了してしまいました。その後、何度 ARRT を立ち上げても、すぐにアプリケーションが強制終了する無限ループに陥りました。
そこで ARRT の config.json の場所を特定し、直接値を編集することで強制終了から抜け出すことができました。という訳で、config.json の配置場所を記載しておきます。

> C:\Users\(UserName)\AppData\Local\Arrt\config.json

```config.json
{
    "arraccount": {
        "accountDomain": "xxxxx.mixedreality.azure.com",
        "availableregions": [
        ],
        "id": "<--- Azure Remote Rendering Account ID --->",
        "key": "<--- Azure Remote Rendering Primary Key --->",
        "regionurl": "xxxxx.mixedreality.azure.com",
        "supportedAccountDomains": [
        ]
    },
    "cameraconfig": {
        "autoGlobalScale": true,
        "cameraInertia": 0.5,
        "cameraRotationSpeed": 0.5,
        "cameraSpeed": 2.5,
        "farPlane": 100,
        "fovangle": 90,
        "globalScale": 1,
        "nearPlane": 0.10000000149011612
    },
    "runningsession": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "storageaccount": {
        "blobendpoint": "<--- Azure Blob Storage Endpoint --->",
        "key": "<--- Azure Storage Account Access Key --->",
        "name": "<--- Azure Blob Storage Name --->"
    },
    "uistate": {
        "inputSelection:defaultContainer": "arrt-sourcemodels",
        "inputSelection:defaultDirectory": "",
        "inputSelection:filterType": "JustAllowedExtensions"
    },
    "videoconfig": {
        "fps": 60,
        "height": 1080,
        "width": 1920
    }
}
```


ARRT に接続情報を入力後、ARRT が強制終了ループになった場合は、こちらのファイルを削除すると、新規で cofig.json が生成されるようです。
私の場合、前回 Azure Remote Rendering を試した際の接続情報と今回の接続情報が競合して、強制終了になっていたようなので、
config.json を削除し、再度接続情報の入力を行うことで正常に動作するようになりました。


- [Azure Remote Rendering Asset Tool ( ARRT ) ｜ GitHub](https://github.com/Azure/azure-remote-rendering-asset-tool)
- [zure Remote Rendering Overview - 概要紹介](https://speakerdeck.com/futo23/mr-dev-days-japan-qian-ye-ji-azure-remote-rendering-falsegoshao-jie)
（Mac）Jupiter notebookでiCloud driveにアクセスする方法


# やりたいこと

複数のMacやiPadでpythonをいじりたいからiCloud driveに置いておきたい
でもJupiter notebook起動するたびにcdでiCloud driveに移動するのはだるい
Jupiter notebookのtreeの一覧からiCloud driveにアクセスしたい

# 解決方法
以下のコマンドでエイリアスを作成しておく

```ruby:qiita.rb
ln -s ~/Library/Mobile*Documents/com~apple~CloudDocs/ iCloud
```

finderの操作で作成したエイリアスではダメみたいだった
なんもわからんコードの調査にシーケンス図を使う

# はじめに

コードを調査する時、初めて読む箇所だと時間がかかることがありますよね。
それにはいろいろな要因があると思うのですが、要因の一つとして、処理の流れをイメージしづらいということがあります。というか私はよくそれが原因で時間がかかります。処理がイメージできないまま開くファイルだけが増えていって、余計にわからなくなります。

この前も初めての箇所を調査することがあって[^1]、試しにシーケンス図を書きながら調査をすると思いのほかうまくいきました[^2]。ここではシーケンス図を使ってよかったことを紹介します。

# シーケンス図ってなに？

UMLのひとつです。ちなみに UML とは、オブジェクト指向プログラミングなどのために考えられた図のことで、いろんな種類があります。
UML のひとつであるシーケンス図はこんなやつです。
初見でも、何が書かれているかだいたいわかると思います。

```plantuml
@startuml
actor front.js
participant back.rb
database database.sql

front.js -> back.rb : request
back.rb -> database.sql : query
back.rb <-- database.sql : return
front.js <-- back.rb : response
front.js -> front.js : rendering
@enduml
```

# シーケンス図の書き方

シーケンス図の書き方はいろいろありますが、私は **PlantUML** というコンポーネントを使っています。
私が仕事で使っている GitLab では、コードブロックで以下のようにすると簡単に書き始められます。

\`\`\`plantuml
(ここに書く)
\`\`\`

他にも、 VSCode で拡張機能をインストールすると扱うこともできます[^3]。

※ひとつ断っておくことがあって、ここでは、正式な書き方に則ってシーケンス図を書くことはせずに、高度なお絵かきツールとしてシーケンス図を緩く利用しようとしています。ちゃんと UML を学んだ人から見るとデタラメな書き方と感じるかもしれません[^4]。すみませんがご了承ください。

# PlantUML でのシーケンス図の文法

基本的な文法は
`[object] -> [object] : message`
です。

ここに詳しく書いてもいいのですが、ちゃんとまとまっているところがあるので紹介します。
-> https://plantuml.com/ja/sequence-diagram


# 良いところ

シーケンス図の良いところを紹介します。

### 気軽に書ける

GitLab での話ですが、コードブロックで `plantuml` とすれば書き始められます。
GitHub でも、Chrome の拡張をインストールすれば使えるようです。

### 挙動が一目でわかる

完成品を見れば、処理の流れや関連のあるファイルが一目でわかります。また、シーケンス図を知らなくても理解しやすいと思います。

### 書きながら処理の流れを理解できる

書くこと自体が調査になります。コードを眺めて途方に暮れることもなく、とりあえず手を動かすということができます。

### わかっている人に見せると、足りていないところを指摘してもらえる

シーケンス図ができたら、該当の処理を知っているつよつよエンジニアに見せましょう。見せられた人も、いまの理解度を把握できるので、教えやすくなります。

# 良くないところ

シーケンス図の良くないところを紹介します[^5]。

### 書くのに時間がかかる

書くのに時間がかかります。あるていど知っているコードの場合は、シーケンス図を使わない方が速く調査できたりします。初めて触るコードが複雑な時に候補に挙がる感じです。

### ちゃんと書こうとすると学習コストが高い

シーケンス図をちゃんと書こうとすると覚える要素が多いです。気になる方は調べてみてください。

### ドキュメントとして残すのには向いていない

ドキュメントとして優秀に見えますが、管理するのに無視できないコストがかかります。チームで書き方を統一しながら、コードを変更するたびにシーケンス図も変更するのは、書く方もレビューする方も、思っている以上に高コストです。
上に書いた学習コストの問題もあるので、ドキュメントとして残すには管理コストの増大を覚悟してください。

# おまけ

PlantUML は json や yaml などの可視化もできます。
以下のように書きます。

\`\`\`plantuml
@startjson
(ここに json を貼りつける)
@endjson
\`\`\`

\`\`\`plantuml
@startyaml
(ここに yaml を貼りつける)
@endyaml
\`\`\`

Qiita ではできないみたいなので、リンクを張っておきます。
-> https://plantuml.com/ja/json
-> https://plantuml.com/ja/yaml

----

以上になります。
利点と欠点を理解して、選択肢の一つとしてご活用ください。

[^1]: 最近は、`vuex` の巨大なコードを追っているときに途方に暮れました。データ構造とアルゴリズムが好きで、グラフの一種である木が得意なので、 `vuex` を使わずに `@prop` と `$emit` で書いてほしいものです。もちろんこれは嘘です。

[^2]: なんもわからん。ってなったので息抜きに書いていたら、思った以上に恩恵がありました。

[^3]: コマンドパレットから `ext install plantuml` でインストールできます。 `java` と `graphviz` が必要なので `brew` や `apt` などで入手します。

[^4]: というか自分がそういう人間の一人だったりします。

[^5]: 当然ですが、良くないところもあります。万物に有効な銀の弾丸なんてありません。
VPSとは何か？

#はじめに
未経験者がVPSについて勉強したことをアウトプットした内容になります

#VPSとは？
物理サーバー上に利用者ごとに仮想サーバーを構築し、利用者それぞれが１台のサーバのように利用できる

![VPS.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1599988/9933a77e-f878-064a-ddab-b0774727e54a.png)

#メリット
・それぞれの利用者がroot権限を持てるため、自分の好きなアプリを入れることができる
・１つの物理サーバーを複数人が共有するレンタルサーバーと比べて、VPSは他の利用者の影響は受けにくい

#デメリット
・アクセスが大規模になったときでも、サーバーのスペックは途中から変更できない
・自分でサーバーの構築やメンテナンスを行う必要がある

#まとめ
レンタルサーバーより自由度は高いが
クラウドサーバーのようなアクセスに応じてスペックを拡張することはできない。

#参考
https://www.winserver.ne.jp/column/vps-aws_distinction/

https://www.inventobserver.com/tips/post-441.html

https://knowledge.sakura.ad.jp/7938/
カレントディレクトリ配下のディレクトリ構成をツリー表示する

### ディレクトリ・ファイルをツリー表示する
``` sh
pwd;find . | sort | sed '1d;s/^\.//;s/\/\([^/]*\)$/|--\1/;s/\/[^/|]*/|  /g'
```
ディレクトリの深さを指定する場合、```find -maxdepth```を指定する（例では3階層)

``` sh
pwd;find . -maxdepth 3 | sort | sed '1d;s/^\.//;s/\/\([^/]*\)$/|--\1/;s/\/[^/|]*/|  /g'
```
pyenvでバージョン変更する際に使うコマンド

### インストール済みのバージョンを表示
```sh
$ pyenv versions
  system
  3.6.12
* 3.8.0 (set by /home/hoge/.python-version)
```

### pythonのバージョン切り替え
globalにすると全体、localにするとカレントディレクトリに反映される

```sh
$ pyenv local 3.6.12
$ python --version
  Python 3.6.12
```
MI実例メモ


記事作成者のメモです。

https://www.hpc.co.jp/chem/materials-informatics/

https://xtech.nikkei.com/atcl/nxt/mag/ne/18/00030/00003/?P=4

https://www.mitsubishichem-hd.co.jp/news_release/00837.html

https://monoist.atmarkit.co.jp/mn/articles/2009/14/news022_2.html

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1786195/5b57f224-344b-7e8f-0f08-364c6081d8de.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1786195/16741544-5578-35f7-26d1-2bc57ff0d87b.png)



https://xtech.nikkei.com/atcl/nxt/column/18/00026/00043/?P=3

https://www.asahi-kasei-jobs.com/career/interview/crosstalk/crosstalk04.html

https://www.brainpad.co.jp/doors/news_trend/materials_informatics/

https://www.y-yokohama.com/release/?id=2896&lang=jp

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1786195/304698b5-176e-5bd0-f812-808a889238f2.png)


https://xtech.nikkei.com/atcl/nxt/mag/ne/18/00030/00003/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1786195/3c3a72b7-de07-cd06-a3ef-7e54e83f25f9.png)

https://www.aist.go.jp/aist_j/press_release/pr2020/pr20201119/pr20201119.html

https://www.mizuho-ir.co.jp/publication/giho/pdf/009_11.pdf


https://www.nedo.go.jp/news/press/AA5_101443.html
rmする際に特定の文字列で始まるファイル(フォルダ)を除外

lsした結果をgrepに渡して、除外したいものを省いてrmに渡す

例、 ```.```, ```..```, ```.ignore```から始まるファイル(フォルダ)を対象外にする

``` shell
ls -a | grep -v -E "^\.|^\.\.|.ignore" | xargs rm -rf
```
OpenJDKって何だっけ？OracleJDKとの違いは？無料？有償？

OpenJDK、OracleJDKの違いについてまとめてみました。
※ここは違うよ！みたいのあれば是非コメント下さい。

## OpenJDK

狭義のOpenJDKは、<font color="red">**バイナリ（JDKの開発者ではなく、利用者であればバイナリを利用するのが通常）を提供していません。**</font>
あくまで、プログラムソースを実装しているOSSのプロジェクトです。
URLは以下。
http://openjdk.java.net/
プログラムソースは以下で管理されている。
https://github.com/openjdk/jdk

じゃあ誰がバイナリを提供をしているのかというと、以下の会社さん等です。
・oracle（oracle open jdk、oracle jdk）
・red hat（red hat open jdk）
・amazon（amazon corretto）
・Microsoft （microsoft open jdk）

で、oracleさんに関しては色々な情報が錯綜している状態かと思いますので、
情報をまとめていきます。

## OracleのJDKに関して

oracleが提供するバイナリは2種類あります。
oracle open jdkとoracle jdkです。

で、oracle open jdkは無料です。
oracle open jdkは、狭義のOpenJDKのURL（ http://openjdk.java.net/ ）
のダウンロードリンク（ https://jdk.java.net/ ）
から取得できます。

で、oracle jdkはjdk 9以降有償（商業利用）でしたが、
jdk17（LTS版：ロングタイムサポートバージョン）では、制限があるものの商業利用でも無償（少なくとも2024年9月までは）になりました。
※オラクルからの商用サポートを受けるにはライセンスが必要と思われる

ライセンス情報は以下。
https://www.oracle.com/downloads/licenses/no-fee-license.html

## まとめ

JDKのソースは2006年（サンマイクロシステムズ時代）からopenだよ
JDKのバイナリ（ディストリビューション）によっては、有償か無償か変わるよ
実行する環境に合わせて、バイナリ（ディストリビューション）選ぼうね
python初学者の備忘録　16進数について

#### [←目次へ](https://qiita.com/dondondon/items/cd45224ca93e65c976cc)

:::note info
python,Qiita初心者なので、備忘録として記載していきます。
なにせ初心者なので、知識不足はご容赦ください。
知識を深めながら追記していきたいと思います。
:::

# 16進数とは

`基本`

+ 0から9までの数字とAからFまでのアルファベットの組み合わせで表現される数字
+ それぞれの桁の数字が「16」になると桁上がりする
+ 10進数を16進数で表すと次のようになる

| 10進数 | 16進数 |
|:-:|:-:|
| 0 | 0 |
| 1 | 1 |
| ~ | ~ |
| 8 | 8 |
| 9 | 9 |
| 10 | A |
| 11 | B |
| 12 | C |
| 13 | D |
| 14 | E |
| 15 | F |
| 16 | 10 |
| 17 | 11 |
| ~ | ~ |
| 24 | 18 |
| 25 | 19 |
| 26 | 1A |
| ~ | ~ |
| 31 | 1F |
| 32 | 20 |
| 33 | 21 |


# 位の説明
**・位は右から順に**

| 位 | 16の累乗 |
|:-:|:-:|
| 1 | 0 |
| 16 | 1 |
| 256 | 2 |
| 4096 | 3 |
| 65536 | 4|
| ~ | ~ |


# 10進数への変換

16進数のAC3という数字があったとする

```python:pythonでの変換
# pythonの場合プレフィックス0xを付ける
>>> 0xAC3
2755
```

分かりやすく説明すると位の表を基準に次にように分解できる
<strong>A</strong>C3：(16*16*10)
+
A<strong>C</strong>3：(16*12)
+
AC<strong>3</strong>：(1*3)
↓
(256*10) + (16*12) + (1*3)
↓
**2755**
となる
python初学者の備忘録　8進数について

#### [←目次へ](https://qiita.com/dondondon/items/cd45224ca93e65c976cc)

:::note info
python,Qiita初心者なので、備忘録として記載していきます。
なにせ初心者なので、知識不足はご容赦ください。
知識を深めながら追記していきたいと思います。
:::

# 8進数とは

`基本`

+ 0から7までの数字の組み合わせで表現される数字
+ それぞれの桁の数字が「8」になると桁上がりする
+ 10進数を8進数で表すと次のようになる

| 10進数 | 8進数 |
|:-:|:-:|
| 0 | 0 |
| 1 | 1 |
| ~ | ~ |
| 6 | 6 |
| 7 | 7 |
| 8 | 10 |
| 9 | 11 |
| ~ | ~ |
| 14 | 16 |
| 15 | 17 |
| 16 | 20 |
| 17 | 21 |
| ~ | ~ |

# 位の説明
| 位 | 8の累乗 |
|:-:|:-:|
| 1 | 0 |
| 8 | 1 |
| 64 | 2 |
| 512 | 3 |
| 4096 | 4 |
| 32768 | 5 |

# 8進数への変換

8進数の213という数字があったとする

```python:pythonでの変換
# pythonの場合プレフィックス0oを付ける
>>>0o213
139
```

分かりやすく説明すると位の表を基準に次にように分解できる
<strong>2</strong>13：(8*8*2)
+
2<strong>1</strong>3：(8*1)
+
21<strong>3</strong>：(1*3)
↓
(64*2) + (8*1) + (1*3)
↓
**139**
となる
python初学者の備忘録　2進数について

#### [←目次へ](https://qiita.com/dondondon/items/cd45224ca93e65c976cc)

:::note info
python,Qiita初心者なので、備忘録として記載していきます。
なにせ初心者なので、知識不足はご容赦ください。
知識を深めながら追記していきたいと思います。
:::

# 2進数とは

`基本`

+ 0と1の組み合わせで表現される数字
+ それぞれの桁の数字が「2」になると桁上がりする
+ 10進数を2進数で表すと次のようになる

| 10進数 | 2進数 |
|:-:|--:|
| 0 | 0 |
| 1 | 1 |
| 2 | 10 |
| 3 | 11 |
| 4 | 100 |
| 5 | 101 |
| 6 | 110 |
| 7 | 111 |
| 8 | 1000 |
| 9 | 1001 |
| 10 | 1010 |
| 11 | 1011 |
| 12 | 1100 |
| 13 | 1101 |
| 14 | 1110 |
| 15 | 1111 |
| 16 | 10000 |
| ~ | ~ |

# 位の説明

+ 位は右から順に

| 位 | 2の累乗 |
|:-:|:-:|
| 1 | 0 |
| 2 | 1 |
| 4 | 2 |
| 8 | 3 |
| 16 | 4 |
| 32 | 5 |
| 64 | 6 |
| 128 | 7 |
| 256 | 8 |
| 512 | 9 |
| 1024 | 10 |
| 2048 | 11 |


# 10進数への変換

2進数の100101という数字があったとする

```python:pythonでの変換
# pythonの場合プレフィックス0bを付ける
>>> 0b100101
37
```

分かりやすく説明すると位の表を基準に次にように分解できる
<strong>1</strong>00101：(2*2*2*2*2*1)
+
1<strong>0</strong>0101：(2*2*2*2*0)
+
10<strong>0</strong>101：(2*2*2*0)
+
100<strong>1</strong>01：(2*2*1)
+
1001<strong>0</strong>1：(2*0)
+
10010<strong>1</strong>：(1×1)
↓
(32*1) + (16*0) + (8*0) + (4*1) + (2*0) + (1*1)
↓
**37**
となる
ABC100 C - *3 or /2 から学んだ

https://atcoder.jp/contests/abc100/tasks/abc100_c

![abc100_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/d81d9007-44f4-761c-3be3-fad40bd7fd02.png)
![abc100_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/0398c942-9bc0-e92e-9a1d-dafd78e5d783.png)
![abc100_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/5767d9fd-6a29-8350-2e1a-75f145d43778.png)
![abc100_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/cee87e3c-6c36-3a98-268f-67868e9a41b9.png)

正直、さっぱりだったので
ご指導を賜りました。

https://www.youtube.com/watch?v=gyJh6k9vOXs

ありがたく頂戴しました。
以下で通りました、はい。

```3or/2.py
N = int(input())
A = list(map(int,input().split()))

cnt = 0

for i in range(N):
    while True:
        if A[i]%2 == 0:
            cnt += 1
            A[i] = A[i]//2
        else:
            break

print(cnt)#82ms
```

***

サッパリ忘れて再チャレンジ。
なんとか通った。

ポイントは**入力 A には 2 が何個入っているかを確認すること**。
3 を何回掛けても 2 は増えない。一方でどれかを必ず 2 で割る。
っと言うことは事は、2 が何個入っていれば分かれば試行回数が分かる。

```abc100c.py
N = int(input())
A = list(map(int,input().split()))

cnt = 0
for i in range(N):
    if A[i] % 2 != 0:
        continue
    else:
        while True:
            if A[i]%2 == 0:
                A[i] = A[i]//2
                cnt += 1
            else:
                break
print(cnt)#80ms
```
Prologで複素関数を学ぶ

#はじめに
自作Prolog処理系のテストも兼ねてPrologで複素数に関するコードを書きました。将来、実用になるであろう量子コンピューターの理解には複素数も関連するとのことです。Pythonなどには数学関数ライブラリが完備されていますが、自分で複素関数の理解、再確認のためにコードを書いてみるのもいいかもしれません。


#飯高先生の本のアイディア
著名な数学者である飯高茂先生の著作に「Prologで作る数学の世界」があります。Prologを応用して集合論、位相、群論について考えを深めていくという内容の名著です。この集合論をPrologで記述する飯高先生の手法にヒントを得て中置記法の演算子を定義し、それで複素関数をPrologで記述してみました。

#コード

```prolog

:- op(700,xfx,isc).

X isc c(R1,I1)+c(R2,I2) :- 
    R is R1+R2,
    I is I1+I2,
    X = c(R,I).

X isc c(R1,I1)-c(R2,I2) :- 
    R is R1-R2,
    I is I1-I2,
    X = c(R,I).

X isc c(R1,I1)*c(R2,I2) :- 
    R is R1*R2-I1*I2,
    I is R1*I2+I1*R2,
    X = c(R,I).

X isc c(R1,I1)/c(R2,I2) :- 
    D is R2^2+I2^2,
    R is (R1*R2-I1*I2)/D,
    I is (R1*I2+I1*R2)/D,
    X = c(R,I).

X isc conjugate(c(R,I)) :-
    X = c(R,-I).

X isc real_part(c(R,I)) :-
    X = R.

X isc imag_part(c(R,I)) :-
    X = I.

X isc abs(c(R,I)) :-
    X is sqrt(R^2+I^2).

```


#実行例

```prolog

N-Prolog Ver 1.83
?- [-'tests/comp.pl'].
yes
?- X isc c(2,3)+c(4,5).
X = c(6,8) .
yes
?- X isc abs(c(2,3)).
X = 3.605551275463989 .
yes
?- X isc conjugate(c(1,2)).
X = c(1,-2) .
yes
?- 

```

#複素関数の理解へ

数学の教科書を片手に複素数における三角関数をPrologで記述してみるなどすると、興味が湧き、理解が深まるものと思います。

#これから10年の間に学ぶべきもの
最新のモダンな言語、言語処理系や新たなライブラリを学ぶことも必要でしょう。一方、現在AIの主流になったDeepLearningでは線形代数と微積分の知識が必要とされています。量子コンピューターにおいては複素関数ほか数学の知識が必要とされるとのことです。そうした基礎を習得しておくこともまた、必要とされる学びではないだろうか？と私は思っています。

#参考資料
社会人のための量子コンピューター超入門　基本数学編
https://qiita.com/Ayumu_walker/items/17e7a947e27823070b40
【TidalCycles】自作関数を別ファイルから呼び出す

# はじめに

TidalCyclesにある程度慣れてくると、自分用の関数をつくったりすることが増えてくると思います。
ただ、TidalCyclesを立ち上げるたびに毎回関数の定義をするためにCtrl+Enterするのは面倒ですし、関数定義が長くなってくるとファイル分割したくなってくると思います。

ちなみに環境は

- OS: Mac
- Editor: Atom

です。

# 関数定義をBootTidal.hsに記述する

Haskellのように`module モジュール名 where`みたいに宣言するだけで.tidalファイルからimportできればいいんですが、この方法では関数定義を別ファイルに切り出すことはできないようです。(できるかもしれませんが、自分が試した限りができませんでした)

[公式のドキュメント](http://tidalcycles.org/docs/configuration/boot-tidal/)によると、BootTidal.hsに関数定義を記述しておけば、TidalCyclesを立ち上げるたびに自動的に読み込んでくれるみたいです。

> Everytime you start Tidal, the software is reading from a configuration file usually named BootTidal.hs.

肝心のBootTidal.hsのありかですが、TidalCycles起動時のコンソールに

```
Load BootTidal.hs from [BootTidal.hsのpath]
```

とでるので、このパスにあるBootTidal.hsを書き換えればよさそうです。(大元のファイルを書き換えない方法は後述しています)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/437488/a928c460-bcc2-9be7-bc37-5e100788ba72.png)

# 関数定義の記述方法

すでに記述されている関数定義を参考に、例えば

```haskell
:{
let elem' xs x = elem x xs
:}
```

のように記述しておけば関数elem'が定義され、使えるようになります。

ちなみに記述する場所は`:set prompt "tidal> "`よりも前であればどこでもいいようです。

# プロジェクトごとにBootTidal.hsを使い分ける

ただ、実際にはこの大元のファイルを書き換えるのは少し抵抗がありますし、ちゃんとプロジェクトごとにGit管理したい気もします。

[TidalCyclesのGithub](https://github.com/tidalcycles/atom-tidalcycles#boot-tidal-path)をみてみると、BootTidal.hsはプロジェクト直下に置いておけばそちらが優先的に読み込まれるらしいので、プロジェクト直下においておきます。

改めてTidalCyclesを立ち上げると、Load BootTidal.hs のpathが変更されていることが確認できると思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/437488/8b12888e-a980-7944-5682-97be0db8cee9.png)

これによって、このプロジェクトのみで使える関数を定義できました。
CH340K の macOS 用ドライバ

[激安シリアル変換 IC の CH340K](https://akizukidenshi.com/catalog/g/gI-16306/) は macOS に搭載されてる CH340 系ドライバでは vender ID が違うので（なぜ…）動かない。

メーカーに問い合わせたら速攻で対応版を作ってくれたとのことで↓以下からダウンロード可能。

https://github.com/LilyGO/LILYGO-T-OI/issues/3#issuecomment-907645945

そのうち[メーカーページ](http://www.wch-ic.com/downloads/CH341SER_MAC_ZIP.html)にものるだろう。
artisan してたら autoload が死んだ

php artisan してたら php artisan が動かなくなった

何を言っているかわからないと思うが

```
[vagrant@localhost hogehoge]$ php artisan
                                   
  [Symfony\Component\Debug\Exception\FatalThrowableError]               
  Class 'Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider' not found  
```

なんか autoload が死んでるくさいんですけど
当然、artisan だけじゃなくてウェブサービスの画面も全部うごかない
artian 動かしてて autoload 死ぬとか意味不明なんですけど
しかも他の適当なライブラリはちゃんと動いてるのでなにもわからない

composer がおかしくなったら　だいたい composer dump-autoload しろとか書いてるけど　全然効果がない

結局、vender 全部消して composer install しなおしたら直った、なにもわからない
Laravelのパスワード再設定のメールをカスタマイズする

# これはなに

公式ドキュメントには手順として簡単なものしかなかったため
Laravelのパスワードリセットのカスタマイズについてメモします。

ResetPasswordNotification.phpでメールアドレスを渡しつつ、
markdownでメールを送信した手順を書き残しておきます。

# 前提

- Laravel Breezeをインストール済みなど、各種認証APIが実装されているものとします。
- メール送信の設定は済んでいるものとします。

### 動作確認環境

PHP8.0
Laravel8


# Modelの変更

User.phpでsendPasswordResetNotificationメソッドを追加してオーバーライドします。

```php:User.php
    public function sendPasswordResetNotification($token): void
    {
        $this->notify(new ResetPasswordNotification($token));
    }
```


# Notificationとテンプレートの設定

コマンドでNotificationを作成します。

```bash
$ php artisan make:notification ResetPasswordNotification
```

$tokenを受け取れるようにします。


```diff:app/Notifications/ResetPasswordNotification.php
+    private string $token;

-    public function __construct()
+    public function __construct(string $token)
    {
+        $this->token = $token;
    }
```

`$notifiable->email`でメールアドレスを取得できます。
クエリパラメーターにのせるとフォームの初期値にできるので渡しておきます。

```php:app/Notifications/ResetPasswordNotification.php
    public function toMail(mixed $notifiable): MailMessage
    {
        $url = urldecode(url('reset-password', $this->token . '?email=' . $notifiable->email));
        return (new MailMessage())
            ->subject('【' . config('app.name') . '】パスワード再設定')
            ->markdown('mail.passwordreset', ['reset_url' => $url]);
    }
```

続いてmarkdownのテンプレートを作成します。

```php:views/passwordreset.blade.php
@component('mail::message')
ボタンを押して、パスワードリセットの手続きを行ってください。

@component('mail::button', ['url' => $reset_url])
パスワードリセット
@endcomponent

----
もしこのメールに心当たりがない場合は破棄してください。

@endcomponent

```


# 画面からテンプレートを確認する

いちいちメールを送信せずともブラウザからテンプレートを確認できるようにします。

```php:routes/auth.php
if (app()->isLocal()) {
    Route::get('/forgot-password-email', function () {
        $user = new User([
            'email' => 'user@example.com',
        ]);
        return (new \App\Notifications\ResetPasswordNotification('test_token'))->toMail($user);
    });
}
```

ブラウザから該当パスへアクセスします。問題なく表示できました。

![qiita_laravel_reset_pass.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17468/603b74b9-5db5-47c8-ecc4-e545a461bafb.png)

テンプレートにLaravelロゴが表示されている場合は、`.env`のAPP_NAMEを `'Laravel'` 以外に設定すると置き換えできます。
Terraform dockerを動かす手順

# はじめに

### 前提

terraform v1.02
docker v20.10.8

# Dockerfile

```docker:Dockerfile
FROM hashicorp/terraform:1.0.2
WORKDIR /terraform
COPY . .
```

公式イメージは alpine で、ENTRYPOINT は["bin/terraform"]になっています。
アクセスキーなどの機密情報がないと terraform が動きませんので、ルートに tf ファイルと terraform.tfvar を作成してコンテナに渡します。

```bash:コンソール
docker build .

docker run コンテナID apply
```

これで apply を行いリソースがつくられます。

# 最後に

自動化するために docker で terraform を動かしましたが正直使いづらいです。
公式でもローカルでの利用を勧めていますので特別事情がない限りはローカルで利用してください。

### 参考

[terraform 公式](https://hub.docker.com/r/hashicorp/terraform/)