OmniAICreator/Qiita-1.07M huggingface dataset:
Colab環境などで、moviepyでエンコーダに nvenc / h264_nvenc を指定してもNoneTypeとしてエラーになり、GPUでエンコードできない

# 結論から先に言うと

moviepyが使用するffmpegが正しく指定できていなかった
以下のコードで明示的にしていしてやる
```Python
from moviepy.config import change_settings
change_settings({"FFMPEG_BINARY":"ffmpeg"})
```

# 起こった事象
Google Colab上でGPUを有効にしたうえで、moviepyの動画エンコードを実施した。
GPUエンコードがされるように `h264_nvenc` を指定したが、該当のエンコーダが無いエラーが表示された
ffmpegコマンドで確認しても、使用可能なエンコーダに含まれているが使用することができなかった

# 解決策
moviepyのissueに同様の事象に対する解決策が記載されていた
参照しているffmpegが異なっていたのか、明示的に使用するffmpegを指定することで解決した
冒頭のコードを、最初に呼び出すことで解決した

https://github.com/Zulko/moviepy/issues/264#issuecomment-183676150
WSL2 で VSCode 拡張機能 (Node.js) のテストコードを実行する

# 概要

Node.js で VSCode 拡張機能を作ると、 `npm run test` でテストを実行できる。
このとき WSL2 上でいくつか生じるエラーがあるので、対処を残す。

# 環境

```
$ npm --version
8.11.0

$ node --version
v17.9.1
```

VSCode 1.71.2
Ubuntu 18.04
Windows 10 Pro

# error while loading shared libraries: xxx

パッケージがインストールされていないので追加する。
xxx に出たパッケージをインストールすること。

```bash
sudo apt-get install libatk1.0-0
sudo apt-get install libatk-bridge2.0-0
sudo apt-get install libgtk3.0
sudo apt-get install libgbm
sudo apt-get install libgbm1
sudo apt-get install libasound2
```

# Missing X server or $DISPLAY

https://www.beekeeperstudio.io/blog/building-electron-windows-ubuntu-wsl2

記載の通り

- [VcxSrv](https://sourceforge.net/projects/vcxsrv/) をインストール
- 設定画面の Additional parameters に `-ac` を追加
- .bashrc に環境変数を追加

```bash:~/.bashrc
export DISPLAY=$(cat /etc/resolv.conf | grep nameserver | awk '{print $2}'):0
export LIBGL_ALWAYS_INDIRECT=true
```

VSCode を再起動すればエラーは消えるはず。
リポジトリのクローンが成功しない時に試して欲しい事

# はじめに
新たにリポジトリをクローンしようとした時に「有効なソースパス/URLではありません」と出て、必要な設定を見直しても見落としが見つからず なかなかクローンができないでいたのですがこの設定をしたところクローンが作れたので、今後のために記事に残します。

# 試して欲しい事　実践
GitHubの自分のアイコンのSettings（設定）からのSSH and GPG keysでSSH keyを確認できると思いますが、それぞれのSSH keyの右寄りの位置に　Configure SSO　というボタンをクリック

**登録したSSH keyがクローン元のアクセスの許可を必要とする場合、ここで承認をします**
下の画像で承認前と承認後の差分です

承認前
![スクリーンショット 2022-10-02 21.06.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2394054/ec069861-590c-11f1-75bd-339cab1eeb81.png)

承認後
![スクリーンショット 2022-10-02 21.20.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2394054/e2f71338-3ced-786d-4b23-d11b022ea805.png)
Pythonで和暦西暦変換を7行で書く

和暦から西暦への変換。最も簡単なコードが欲しかったのでいろいろ探すのが面倒で自分で作った。

```wareki2seireki.py
import re
def wareki2seireki(wareki_s, def_value=0):
    era_dic = {"明治": 1868, "大正": 1912, "昭和": 1926, "平成": 1989, "令和": 2019}
    s = re.match(r'(明治|大正|昭和|平成|令和)([0-9]+|元)年', str(wareki_s))
    if s is None: return def_value
    y = int(s.group(2)) if s.group(2) != '元' else 1
    return era_dic[s.group(1)] + y - 1

print(wareki2seireki('昭和60年'))
print(wareki2seireki('令和元年'))
```
【Git】マージされたリモートブランチを自動削除する方法【GitHub】

## 設定方法
以下の手順でマージされたリモートブランチの自動削除を設定できます。

リポジトリの「Code」の画面から「Settings」をクリックします。
![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f323334323434332f38316634396562612d643965622d353563642d386366302d3630313433383534333935652e706e67のコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/325a89a7-6a31-3f5e-438f-2ac3cbd9b923.png)

「Settings」画面の「General」をクリックし、下にスクロールします。

![スクリーンショット 2022-10-02 22.01.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/d5ef5b7d-d35c-be9d-89f4-5f95d47ff00a.png)


「Pull Requests」という項目がありその中の「Automatically delete head branches」にチェックを入れます。
![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f323334323434332f38353431333330622d633263612d656666342d393861632d3466366231373733303362342e706e67のコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/8337fb44-eabc-b402-e026-c661774562e9.png)

## コマンドで設定
コマンドで上記の設定をする場合には以下のように実行します。

```zsh
gh repo edit ユーザー名/リポジトリ名 --delete-branch-on-merge
```
Rails7 importmapを使用してJavaScriptを読み込もう！

## Rails7でJavaScriptを読み込む方法について
Rails7でバンドルツールが変更されたため、備忘録もかね執筆しました。

:::note warn
本記事は`importmaps-rails`を使用した`JavaScript`の読み込み方法です。
`Bootstrap`や、`postCSS`を使用している方は`esbuild`でビルドを実施してください
:::

### 対応手順
以下は`app/javascript/files`配下に配置した`test.js`が読み込まれるようにするための設定です。

#### 1. `application.js`でファイルをロード
エントリーポイントの`app/javascript/application.js`に読み込むファイルをパス指定

```javascript
import "@hotwired/turbo-rails";
import "controllers";

// 追記
import "./files/test";
```

#### 2. `importmap`へのマッピング

`importmap`で使用している`config/importmap.rb`にファイルが読み込まれるように記載します。

```ruby
# Pin npm packages by running ./bin/importmap

pin "application", preload: true
pin "@hotwired/turbo-rails", to: "turbo.min.js", preload: true
pin "@hotwired/stimulus", to: "stimulus.min.js", preload: true
pin "@hotwired/stimulus-loading", to: "stimulus-loading.js", preload: true
pin_all_from "app/javascript/controllers", under: "controllers"

# 追記
pin_all_from 'app/javascript/files', under: 'files'
```

### [補足] importmap の 基本的なコマンド
- `pin`
    - 指定したファイルをマッピングに追加
- `pin_all_from`
    - 指定したディレクトリ以下のファイル一式をマッピングに追加

#### :memo: npmパッケージを利用する場合
```bash
bin/importmap pin react
```

実行後、`config/importmap.rb` にパッケージのマッピング情報が追加されていると思います。
```ruby
pin "react", to: "https://ga.jspm.io/npm:react@17.0.2/index.js"
pin "react-dom", to: "https://ga.jspm.io/npm:react-dom@17.0.2/index.js"
pin "object-assign", to: "https://ga.jspm.io/npm:object-assign@4.1.1/index.js"
pin "scheduler", to: "https://ga.jspm.io/npm:scheduler@0.20.2/index.js"
```

以上です。
登録したファイルが読み込まれているか、確認してみてください。
【AWS】AWS Certified Machine Learning - Specialty 合格体験記 - 2022年10月01日

# AWS MLSについて
MLSは機械学習に関する専門知識の分野に属する資格になります。
※赤枠が現状私が取得済みの資格になります。
![AWS資格一覧.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2512673/1886677d-0fee-4611-3ff3-b804daa5df5d.png)

# 結果
2022年10月01日に受験し、無事「合格(828点)」でした。

# 勉強方法
[Tech Stock（旧 AWS WEB問題集で学習しよう）](https://aws.koiwaclub.com/)の有料会員になって
#01-#22を4周しました。間違えた問題を解きなおす機能が増えたので勉強しやすくなっていると思います。
Tech Stockだけだと問題数が少ないのでexamtopicsも併せて勉強しました。

# 勉強期間
8/31に勉強開始、10/01に試験を受けてきたので約１ヶ月の勉強期間です。

# 総評
他の体験記でも記載が多いですが機械学習の基本的な知識が必要になります。
AWSのサービスだけ勉強してもどうにもなりません。私は機械学習の基礎がなかったので苦労しました。
とにかく問題を解き、なぜそのサービスを利用して機械学習のパターンを利用するのか覚えました。

次回はいい加減DevOpsを受けようかなと思ってます。
開発経験が少ないのでなかなかの厳しさかもしれませんがチャレンジしてきたいと思います。

残りのAWS資格は以下です。
・AWS Certified Cloud Practitioner
・AWS Certified DevOps Engineer - Professional
・AWS Certified: SAP on AWS - Specialty
もうルーチン業務を忘れない!時間でアラームが鳴るWebアプリ



# はじめに
毎日のルーチン業務を忘れないようにする為に、ノーコードのデジタル技術と既存の仕組みを利用して、アラームを出すWebアプリを作成してみました。

# 使ったサービス
下記のサービスを使用しました。
◆[CodePen](https://codepen.io/)
◆Google(Edge等でも良いです)

# 出来上がり
こんな感じになります。
<blockquote class="twitter-tweet"><p lang="zxx" dir="ltr"><a href="https://t.co/1NZ9LdjLok">pic.twitter.com/1NZ9LdjLok</a></p>&mdash; さぬきうどん (@oArjjVOaaLVLG8N) <a href="https://twitter.com/oArjjVOaaLVLG8N/status/1576554794214625280?ref_src=twsrc%5Etfw">October 2, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# 作り方
1.CodePenで共有されている成果物をベースにしてWebアプリを作成します。
ベースは、AMPMでアラームをセットする事により、時間になるとアヒルの鳴き声が聞こえる仕様となっていましたので、見出しや文字の色などを加工しました。
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="LYmmQvw" data-user="ktnzrtzqwvrmeji" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/ktnzrtzqwvrmeji/pen/LYmmQvw">
  Alarm clock in Vanilla Javascript</a> by 白川圭司 (<a href="https://codepen.io/ktnzrtzqwvrmeji">@ktnzrtzqwvrmeji</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

2.スマホでの動作を想定していましたが、iPhoneで稼働しない事が判明した為、同僚のテスト用にパソコンでの自動起動も準備設定しました。
![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2792549/235643af-1863-a4da-b89b-5d0b0a0e69ef.png)
![図2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2792549/0346ae8a-0f70-e01d-3f12-b632b84884a7.png)

3.同僚よりフィードバックを頂き、CodePenで共有されている別の成果物を組み合わせて、改善しました。
・午前中に時間がズレることを改善
・アラーム設定時刻を5件までセット可能に改善
・24時間表示に変更
・音以外の表示も追加
※ヒアリング詳細は、note記事を参照願います。
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="dyedOWo" data-user="ktnzrtzqwvrmeji" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/ktnzrtzqwvrmeji/pen/dyedOWo">
  Task alarm4</a> by 白川圭司 (<a href="https://codepen.io/ktnzrtzqwvrmeji">@ktnzrtzqwvrmeji</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

# おわりに
幾つかの改善はできましたが、解決しなかった課題もありました。
時間連動する留めるWebアプリである為、スマホがベターだったのですが、実現できませんでした。音をストップさせる機能が、複数の成果物を共有した事で、組み合わせしきれませんでした。
セットしたアラームを残す方法も探しきれませんでした。
また、再トライする時間も作れず、自分の確認となった事は悔やまれます。

ただ、フィードバックを頂いて、ルーチン業務をお手軽にリマインドさせるには、方法としては使えそうだなという感覚を持ちましたので、時間を作って残る課題も解決して使い勝手の良い物にしていきたいと考えています。
Excelでソースコードを書いてみる

# 動機
先日[Arduino（マイコン）からモールス信号を送信する（C++）](https://qiita.com/admiralhetare/items/79c47412d4cd454b0c14)という記事に書いた通り、モールス符号表をC++で書きました。
賢い書き方を知らないというのもあって、泥臭く書くことにしましたが…流石に人間様の仕事ではありません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2271250/b46e8c2a-3564-38d7-5405-9c3bc1262b26.png)
俺にはこの道具しかないんだ！というわけで、エクセルのオートフィルとか使ってコードを書いてしまいましょう。
# Webページのtableはエクセルにコピペできたりする
[モールス信号（復号）](https://tomari.org/main/java/morse_dec.html)のコード表がなんとエクセルにコピペでエクセルに貼り付けられました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2271250/1e32c233-623c-339e-b02b-b64bd25d6f18.png)
一気に加工が楽になりましたね。正直、この部分が一番ありがたい。
# エクセルでテキストを変換していく
LEN関数で文字数をカウントして…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2271250/7e338676-7107-046b-95e8-99ece0487888.png)
MID関数で符号文字列をばらばらにして…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2271250/2b003dfb-e800-ecec-07f3-ce6467006035.png)
IF関数とか駆使して自分で#defineした文字列に置換します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2271250/f2083674-fd1b-110e-8aea-74bfd4c9de30.png)
後はソースコードにするのに必要な制御文字とかを結合してあげれば完成です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2271250/23723512-cbb4-dc72-56a1-6ebd21581088.png)
タブ区切りテキストやcsvとかで保存してあげるとソースコードの出来上がりです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2271250/07106ae7-0a53-c0b7-0f5d-2de5716a16fc.png)
コード整形はVSCodeにお任せしてしまいましょう。
# メリットデメリット
## メリットになりそうだと思った点
- 法則性があるデータの配列とかをオートフィルで作っていける
- webページのtableを貼り付けられる
- 加工のやり方を記録できるので、再利用できる
## デメリットかなと思った点
- エクセルってそういうツールでしたっけ？という疑問
- 開発環境にそういうことができるツールあるんじゃないのか？という疑問
- いや、そもそもソースの書き方が悪いのでは？という疑問

あまりスマートではありませんが、こういうやり方もあるということで、ここはひとつ。
機密情報の取り扱い【1Passwordを使ってみて】

### はじめに

システム開発を行っていると様々な機密情報を取り扱う場面に出くわします。
WebサイトのIDパスワード、APIキー、SSHの秘密鍵・公開鍵等々、機密情報は多岐に渡ります。
このような機密情報を管理する有料のツール「1Password」を使ってみた感想をお伝えしたいと思います。

### 1Passwordとは？

パスワードなどの機密情報を管理する有料のサービスです。

これだけ聞くと
「有料？ Chromeのパスワードマネージャーで十分では？」と思うかもしれません。

パスワードだけでなく様々な機密情報を
厳重なセキュリティの元にクラウド上に保存してくれるサービスです。

以下のような情報を管理することができます。

![スクリーンショット 2022-10-02 16.58.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261675/db16a422-f60f-95d3-b9ae-d76f723a5da1.png)
（社会保障番号や狩猟免許というのがアメリカンな感じがする）

### 動作環境

1Passwordが対応している環境は次の通りです。

Mac、Windows、Linux、iOS、Android
Web（Chrome、Safari、Edge、Firefox、Brave）

### 便利なところ

機密情報を管理できるのが嬉しいことではありますが
普段使いで特に便利な点を挙げておきたいと思います。

**ワンタイムパスワード**

ブラウザの拡張機能をインストールすることで
IDパスワードなどを自動入力できるようになります。

これだけだと、ブラウザのパスワードマネージャーで十分だと思いますが
二要素認証のワンタイムパスワードにも対応している点が素晴らしいです。

Google Authenticator、Microsoft Authenticator などの
ワンタイムパスワードアプリを使うような場面で
事前にこれらのアプリの代わりに1Passwordを二要素認証として設定しておくと
IDパスワードの自動入力後に、ワンタイムパスワードも自動入力されます。

これまでだと、
PCでログインする時にスマホを出してワンタイムパスワードを表示して
PCに入力するといった手順を踏んでいたことから解放されます。

また、ワンタイムパスワードのアカウントが多いとスマホの機種変更時の引っ越しも大変でした。

**SSHキー秘密鍵・公開鍵**

SSHのログインやGitHubリポジトリへのアクセスなど、昨今SSHキーの利用が増加しています。
そういったSSHキーをクラウドに保持しつつ、
必要に応じて1PasswordからSSHクライアントに提供することでセキュアな接続を可能とします。

ssh/configのサンプル

```
Host 設定名
  HostName ホスト名
  User ユーザー名
  # 従来の記述 →  IdentityFile ~/keys/ファイル名.pem
  IdentityAgent "~/Library/Group Containers/********.com.1password/t/agent.sock"
```

IdentityFileによるキーファイルの指定から
IdentityAgentによるキー情報の提供へ変更

全てのSSHクライアントをサポートしているわけではないので注意が必要です。

### セキュリティやサービスダウンは大丈夫？

クラウドに機密情報を置く場合
セキュリティ的に大丈夫なのか、サービスがダウンして使えなくなったりしないか、といった点が気になります。

**セキュリティについて**
公式サイトに詳しく書かれていますが
それよりも採用している企業を見れば安心が得られるかもしれません。

採用企業は、IBM、Slack、Shopify等々、ユーザー数1500万。
Appleが全社員にアカウントを配布したというニュースもありました。

**サービスダウンについて**
Saasで心配なのはサービスがダウンしてデータにアクセスできなくなってしまうことです。
これについては、専用アプリが提供されていて、
このアプリがオフラインでも動作するので既存データにアクセスできなくなることはなさそうです。

もしもサービスが落ちた場合は、クラウドを通じたデータの同期はできなくなるので
最新データの同期についてはサービスの復旧を待つ必要がありそうです。

### サービスロックインが心配

専用アプリにエクスポート機能がついています。
さらにIDパスワードだけはCSVに書き出せるようなので、
手間は掛かるかもしれませんがサービスロックインは回避できると思います。

### 有料サービスなんです

1Passwordは有料サービスです。
「あぁ、有料か。じゃあ使えないなぁ」と思うかもしれません。

システム開発とかしてると、
オープンソースとか使って何とか無償でやりくりするクセがついてたりするかもしれません。
もし、あなたがソフトウェア開発を生業にしているのであれば、
ソフトウェアにお金を支払う価値があることは当然理解していると思います。

1Passwordもお金を支払うに値するソフトウェアの一つだと思います。
（機密情報を沢山持っている人に限ってですが）

念の為、私は1Passwordの利害関係者ではありません。

### 最後に

これまで機密情報に関して

・失くさないように
・漏れないように

とあれこれ工夫して管理していましたが

量も種類も多く、時間も取られて大変でした。

有料ではありますが、というかお金を払うことで
こういった煩わしさから解放されたように思います。

昨今、Appleはicloudでのパスワード管理を進めています。
もしかすると機密情報管理は将来的にはそういったものに吸収されるのかもしれません。
それまでもう少し1Passwordを使っていこうと思います。
Googleニュースをpythonで取得する（RSS利用）

Googleニュースをpythonで取得したくて、試した内容を備忘録的にメモしておきます
## ライブラリを使ってみた（断念したもの）
まず初めに以下のライブラいを試してみました
https://pypi.org/project/GoogleNews/
しかし取れるデータが2年前くらいになってしまったので使用を断念しました。
（日本のニュースだと駄目なのかな？）

## 最終的に使ったもの
色々調べると以下のサイトでGoogleNewsのRSSが取れることを知りました。
https://qiita.com/KMD/items/872d8f4eed5d6ebf5df1

その後にfeedparserを使いました。
```
$pip install feedparser
```
そしてRSSのデータは日付が以下のような形式のため、datetimeを使って変換しました。
```
Sun, 02 Oct 2022 03:28:43 GMT
```

最終的なものは以下のもの（シンプルなもの）
```
import feedparser
import datetime

keyWord = '田中先生'
rssDatas = feedparser.parse('https://news.google.com/rss/search?q=%27' + keyWord + '%27&hl=ja&gl=JP&ceid=JP:ja')
for rssData in rssDatas.entries:
  # 日付を変換
  updateTime=  datetime.datetime.strptime(rssData.published, '%a, %d %b %Y %H:%M:%S GMT').strftime('%Y/%m/%d')
  print('----'*30)
  print('タイトル：',rssData.title)
  print('日時：',updateTime)
  print('リンク：',rssData.link)
```

取得できたデータは以下のようなもの

```
タイトル： 小倉唯さんがCVを担当！Switch／PS4『サマータイムレンダ Another Horizon』ゲームオリジナルキャラクターを公開（アスキー） - Yahoo!ニュース - Yahoo!ニュース
日時： 2022/09/21
リンク： https://news.yahoo.co.jp/articles/f3ae199a29626f98c916a0653ee58f85abe5f524
------------------------------------------------------------------------------------------------------------------------
タイトル： 串カツ田中HDは「助成金頼み」てなんとか黒字化…本格離陸はいつになるのか？（有森隆）（日刊ゲンダイDIGITAL） - Yahoo!ニュース - Yahoo!ニュース
日時： 2022/09/15
リンク： https://news.yahoo.co.jp/articles/27f1fed68d182444d3dcceb31fde5b62b4ba3c77
------------------------------------------------------------------------------------------------------------------------
タイトル： 【国際日本学部】田中絵麻ゼミナール「ICTを活用して、日本が抱えるさまざまな課題を解決する政策や企業の取り組みを研究！」 - MEIJI NOW
日時： 2022/09/26
リンク： https://meijinow.jp/study/seminar/73021
```
【Git】コマンド早見表

## 概要
Gitコマンドの自分向けの備忘録です。

## コマンド一覧

現在の差分状態を知る
```
git status
```


ステージング
```
git add . 
```

コミット
```
git commit -m"コミットメッセージ"
```

プッシュ
```
git push origin ブランチ名
```
M1 macでDockerを使用してMySQLの実行環境を構築する方法

こんにちは、JeffTechです。

# やりたいこと
M1 macbook AirでDockerを使ったMySQL5.7の実行環境を構築する

# 開発環境
M1 Macbook Air
Docker
MySQL 5.7

# 実装手順
- プロジェクトディレクトリ作成
- docker-compose.ymlを作成
- docker-composeコマンドの実行
- MySQLへ接続

# 実装

## プロジェクトディレクトリ作成

どこでもいいので今回MySQLを構築するためのディレクトリ（フォルダ）を作成して、適当に名前を付ける。

## docker-compose.ymlを作成

先ほど作成したプロジェクトディレクトリ配下に`docker-compose.yml`を作成し、下記の通り編集する。

```yaml
version: "3"

services:
  mysqldb:
    image: mysql:5.7
    platform: linux/amd64
    container_name: mysql_container
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: my_testdb
      MYSQL_USER: docker
      MYSQL_PASSWORD: docker
      TZ: "Asia/Tokyo"
    volumes:
      - ./docker/db/data:/var/lib/mysql
      - ./docker/db/my.cnf:/etc/mysql/conf.d/my.cnf
      - ./docker/db/sql:/docker-entrypoint-initdb.d
    ports:
      - 3307:3306
    command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
```

自分の環境だとすでに3306ポートが埋まっており、3307ポートを指定している。

3307ポートも埋まっている場合は3307の部分を3308などにする。

## docker-composeコマンドの実行

```bash
$ docker-compose up -d
```

## MySQLへ接続

### rootで接続する場合

```bash
$ mysql -h 0.0.0.0 -P 3307 -u root -p
```

`-> Enter password`と聞かれるので`root`を入力してエンターを押下。

### docker(docker-compose.ymlで指定したユーザー)で接続する場合

```bash
$ mysql -h 0.0.0.0 -P 3307 -u docker -p
```

`-> Enter password`と聞かれるので`docker`を入力してエンターを押下。

# 最後に
少しでも役に立った！という時は、いいねをポチッとして
フォローしてくださると嬉しいです、、、笑

役に立たなかった時は、怒らないでコメント頂けますと幸いです笑

Twitterもやってますので、よかったら見てみてくださいね！
https://twitter.com/jefftechsaku
Mapbox GL JS 円をつなぐ線を得る

とあるハッカソンで、台風の進路を投票で決めるというジョークアプリを作成しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/5d0ac42a-80be-5b58-f554-41119b2ea679.png)
[動画](https://youtu.be/Ex_dubH1Myo)

アプリ製作にはmapboxを用い、補助として[Turf.js](https://turfjs.org/)を使用しました。
Turf.js、めちゃめちゃ便利でmapboxでの開発速度が爆上がりしたのですが、
さすがに「円のリストをつなぐ線を引く」といった関数まではなかったので用意しました。
Turf.jsを利用しているのでとても簡単に実装できています。

```
// get 2vertices line array from circle array
// in:[{coord:[lng,lat],radius:r},{coord:[lng,lat],radius:r},{},...]
// out [lineStringGeojson,lineStringGeojson,...]
getEmvelopeLineArrayFromCirclleArray = function(_circleArray){
    var outArr=[];
    if(_circleArray.length > 1){
        for(var i=0;i<_circleArray.length-1;++i){
            // １番目の円の中心
            var pt0 = turf.point(_circleArray[i+0].coord);
            // ２番目の円の中心
            var pt1 = turf.point(_circleArray[i+1].coord);
            // 直線pt0-pt1の角度
            var ang = turf.rhumbBearing(pt0,pt1, {units: 'kilometers'});
            var pos0a = turf.rhumbDestination(pt0,_circleArray[i+0].radius,ang-90, {units: 'kilometers'}); // pt0から、直線pt0-pt1に垂直で、距離が１番目の円の半径である場所
            var pos0b = turf.rhumbDestination(pt0,_circleArray[i+0].radius,ang+90, {units: 'kilometers'}); // pt0から、直線pt0-pt1に垂直で、距離が１番目の円の半径である場所(反対側)
            var pos1a = turf.rhumbDestination(pt1,_circleArray[i+1].radius,ang-90, {units: 'kilometers'}); // pt0から、直線pt0-pt1に垂直で、距離が２番目の円の半径である場所
            var pos1b = turf.rhumbDestination(pt1,_circleArray[i+1].radius,ang+90, {units: 'kilometers'}); // pt0から、直線pt0-pt1に垂直で、距離が２番目の円の半径である場所(反対側)
            outArr.push(turf.lineString([pos0a.geometry.coordinates,pos1a.geometry.coordinates])); // 直線geojsonを作成してpush
            outArr.push(turf.lineString([pos0b.geometry.coordinates,pos1b.geometry.coordinates]));
        }
    }
    return outArr;
}
```
円のリストを渡すと頂点数２のLineリストが返ってくるので、
```
var LineArr = getEmvelopeLineArrayFromCirclleArray(tmpCircleArr);
if (!map.getSource('multiLineEmvSrc')){
    map.addSource('multiLineEmvSrc', {
        'type': 'geojson',
        'data': {'type': 'FeatureCollection', 'features': LineArr}
    });
}
if (!map.getLayer('multiLineEmv')){
    map.addLayer({
        'id':'multiLineEmv',
        'type':'line',
        'source':'multiLineEmvSrc',
        'layout': {},
        'paint': {
            'line-color': '#fff',
            'line-width': 1,
            'line-opacity': 0.5
        }
    });
}
```
のようにaddSource()/addLayer()してあげると円を結ぶ線を引いてくれます。
【基礎】HTMLタグ備忘録

# 初めに
<b>9月中旬から仕事をしながらHTML/CSSの勉強を始めて２週間ほど経ったので自分が勉強している中で頻出しているタグをまとめてみました。
<br>間違ってる所等あればどんどん教えてください。
<br>また、マークダウンで文章を書くのが初めてなので読みづらい点もご了承ください。


## HTMLの雛型として必須なタグ
<dl>
  <dt>htmlタグ</dt>
  <dd>これがなきゃHTML文が始まらない必須タグ、文書がHTMLなんだと分からせるタグ</dd>
  <dt>headタグ</dt>
  <dd>ブラウザで表示されないhtml文書の決まり事とかを書くエリアを囲むタグ</dd>
  <dt>bodyタグ</dt>
  <dd>ブラウザで表示される文書を書くエリアを囲むタグ</dd>
  <dt>metaタグ</dt>
  <dd>headタグ内で色々な文書のルールを書くために使われるタグ、終了タグがいらない</dd>
</dl>

## bodyタグ内で使われるタグ
<dl>
  <dt>h1~6タグ</dt>
  <dd>この文書は見出しだよというタグ、1じゃない数字から始めるのは原則ダメ、数字は順番通り</dd>
  <dt>pタグ</dt>
  <dd>このタグで囲むと文書が一つ下の段落で表示される、段落が違う文書だよというタグ</dd>
  <dt>divタグ</dt>
  <dd>主にCSSの装飾の為にクラスが振られるタグ、タグ自体に意味はないがブロック要素のため、囲んだ文書はそれぞれ段落になる、flexboxでめっちゃ使う</dd>
  <dt>spanタグ</dt>
  <dd>divタグと同じようにこのタグ自体に特に意味はないがこれもCSSでの装飾でよく使われるタグ、divタグとの違いはインライン要素の為、改行しないので文中の一部の文字色を変えたりするのに使う</dd>
  <dt>aタグ</dt>
  <dd>タグで囲んだ文書にリンクを貼るのに使うタグ、href属性でリンク先を指定できる</dd>
  <dt>imgタグ</dt>
  <dd>画像を貼るのに使うタグ、終了タグがない、hrefではなくsrc属性で貼りたい画像の場所をリンクする</dd>
  <dt>ul,liタグ</dt>
  <dd>ulタグで囲んだliタグがリストになるタグ、単純に箇条書きのリストとかによく使う、olタグという順序立てたリストを作るタグもあるが、個人的にはあまり見ない</dd>
  <dt>dl,dt,ddタグ</dt>
  <dd>用語と用語の説明で使うタグ、dtで囲んだ所が用語説明今からやりまーすみたいな宣言、dlタグが用語、ddタグがdlに書いた用語の説明文になる</dd>
</dl>

## bodyタグ内のHTMLを読みやすく使うのに使うタグ
<dl>
  <dt>headerタグ</dt>
  <dd>ページのヘッダー部分だよと分かってもらうタグ</dd>
  <dt>mainタグ</dt>
  <dd>ページのメイン部分だよと分かってもらうタグ</dd>
  <dt>footerタグ</dt>
  <dd>ページのフッター部分だよと分かってもらうタグ</dd>
  <dt>asideタグ</dt>
  <dd>広告とかメニューとか直接コンテンツに関係のないものをここで書いてると分かってもらうタグ</dd>
  <dt>sectionタグ</dt>
  <dd>文章のセクションを表すタグ、結構使いやすくて個人的にはmainタグの中でバンバン使う</dd>
</dl>

## 終わりに
個人的に学習の中でよく使っていて忘れないための備忘録の面が強いので、あまり参考にはならないかもしれないですが、HTMLの基礎勉強の中だと使われてるタグはほとんどの学習プラットフォームでこれくらいかなと思います。
個人的Droidkaigi2022特に気になるトーク

[Droidkaigi2022](https://droidkaigi.jp/2022/)開催日が近くなってきました。

タイムテーブルが公開されたので、気になるトークをピックアップしてみました。


# Jetpack Compose で Material Design 3
１日目の 11:15-11:55
ComposeはAndroidの今のトレンドだと思うので、 Compose で Material Design 3というのはキャッチアップしておきたい内容だと思います！


# AndroidManifest.xmlはその後どうなっているのか？
１日目の 14:20-14:45
AndroidManifestは記載することが必要なので、なんとなく書いていることが多いと思います。
その後どうなっているかは、あまり考えていなかったのでこれを機に理解を深めていきたいです！

# Camera Xライブラリの魅力と最新機能を紐解く
１日目の16:35-17:00
さまざまなアプリでカメラ機能は使用していると思うので、カメラ機能のライブラリーの最新情報は知っておいて、損はないと思います！


# 実例から学ぶJetpack Composeのパフォーマンス改善
Composeを実例からパフォーマンスについて理解を深めることができるのは嬉しいですね！
意図せずに、必要以上の広範囲で高速に更新処理をしてしまっているかも知れないので、聞いておいたほうが良さそうです！


# 2022年の動画再生アプリの作り方
アプリで動画再生を実装するための最新のノウハウが聞けるのは良さそうです。
自分は動画再生の機能は、3年前に実装して、それ以降実装していないので、どのように変化しているのか気になります！


# 終わり
個人的Droidkaigi2022特に気になるトークでした。他にも気になるトークはありますので、みなさんも[タイムテーブル](https://droidkaigi.jp/2022/timetable)の確認を今のうちにしておくと良いでしょう！
Dockerを学習し始めた浦島太郎は感動した

こんばんは。

週明けから、面談を受けつつ、学習をし、適度に遊ぶ、という生活が始まります。
前回の記事で、「ブランクがあるため新しい技術を学びたい」といった旨のことを書きました。今って環境構築にDockerを使いますよね。モダンな会社は〜とも聞きますが、主流になってきているというか、主流なんじゃないか？と思っています。違ったらご指摘ください。

というわけで、UdemyでDockerの基礎から学習していきます。
（2022.10.02現在、Udemyセールしてますよ）

# 視聴している動画

https://www.udemy.com/course/docker-startup/

# 分かったこと、疑問など

### 環境構築が楽（そのまんまですね）

まず、以下のようなことをしなくて済む、ということが分かりました。
（VirtualBoxとVagrantであれやこれや…）

https://qiita.com/sowayaca/items/a06b3b0088e889218eaa

バージョン違いとかサーバーの仕様でハマるといったことがほぼ無くなった、という感じでしょうか。浦島太郎気分です、純粋に感動してしまった。

また、OSが違っても同じように動くのは有り難いですね。
プログラマしてた時、上に記載した記事にあるとおり、私だけMacでみんなWindowsだったんですよ。だから同じ環境を作ることが難しかった。またWindowsにはあるけれど、Macにはない、絶妙に手の届かないソフト（今はアプリと呼びますね）があったりしました。

### インフラ設計が必須の世の中になった

コンテナ型って何って思っていたのですが、想像図は頭の中に描くことができました。
ただ、Dockerで肝になるのはインフラ設計なんじゃないかと。運用方法とか、構造とか、初期段階での設計が大事になってくるのでしょうか（まだ動画は途中なので、もしかしたら運用体制は後からでも容易に変更できるのかもしれませんが）。

でも昔ながらの環境構築でもサーバをどうするかは必須事項ではあったので、その点に変わりはないのだろうな、と思います。

### 反対に、Dockerを導入するデメリットはないの？
動画内ではDockerのメリットしか今のところ話されていません。

#### 個人的に予想しているデメリットと疑問

**・環境依存は無くなったが次はツール依存が起きるのでは**
Dockerに限らず、よくある話だと思いますが、「Dockerを使うなら今度はkubernetesだ」、みたいな。でもどんな時代のいかなる技術も、完璧なことってないから、逆にそれくらいのデメリットしかないなら導入を検討しますよね。

**・古い環境からの引っ越しはできるの？**
これはまだ学習していない分野かもしれません。ただ、いくら今の主流がDockerだったとしても、保守されているものはまだまだひと昔前の技術が使われているのではないでしょうか。そういったとき、Dockerがどのように使えるのか、気になります。

------
「インフラのコード化」は面白いですね。本当に浦島太郎なので、「すげえ〜」ってなってました。でもそういう設計をするのは（個人でする分には）楽しそうなのでトライしたいですね。（M1チップにDockerが対応した、と聞いています）

まだまだ動画も見始めたばかりだし、コードも実際に自分で書いてみないとだと思うので、これからもこのような形での記事になっていくかと思います。

おしまい。
【読書感想文】京極夏彦「地獄の楽しみ方」を読んで

# はじめに
今日、京極夏彦さんの「地獄の楽しみ方」という本を読みました。
その内容について、感じたことを自分なりに纏めたいと思ったので記事に残します。


## 今回読んだ本
https://www.amazon.co.jp/%E6%96%87%E5%BA%AB%E7%89%88-%E5%9C%B0%E7%8D%84%E3%81%AE%E6%A5%BD%E3%81%97%E3%81%BF%E6%96%B9-%E8%AC%9B%E8%AB%87%E7%A4%BE%E6%96%87%E5%BA%AB-%E4%BA%AC%E6%A5%B5%E5%A4%8F%E5%BD%A6-ebook/dp/B09V11K4C3/ref=sr_1_1?adgrpid=134671096995&gclid=CjwKCAjw7eSZBhB8EiwA60kCWyK6DYymKbbA4Z1oc1pP966H4qYbIfCSeKjPpwQZ5UY8My8KsqdSdhoC4CkQAvD_BwE&hvadid=611262186936&hvdev=c&hvlocphy=1009304&hvnetw=g&hvqmt=b&hvrand=12277530466780605051&hvtargid=kwd-1648239093057&hydadcr=4074_13255661&jp-ad-ap=0&keywords=%E5%9C%B0%E7%8D%84%E3%81%AE%E6%A5%BD%E3%81%97%E3%81%BF%E6%96%B9+%E4%BA%AC%E6%A5%B5%E5%A4%8F%E5%BD%A6&qid=1664706913&qu=eyJxc2MiOiIxLjQ4IiwicXNhIjoiMS4wNCIsInFzcCI6IjAuNzMifQ%3D%3D&sr=8-1

電子版も出ているようなので、ぜひ読んでみてください。

## どんな本なの？
京極夏彦さんといえば、「姑獲鳥の夏」や「魍魎の匣」などといった京極堂シリーズなどのイメージをお持ちの方が多いかと思います。
（いずれも非常に面白い作品です）
しかし今回の「地獄の楽しみ方」は小説ではなく、京極さんが小説家として考えている「言葉」というもの、その扱い、考え方について講演形式でまとめられた内容になっています。

## どう活かせそうなの？
エンジニアは
* 仕様書、設計書などのドキュメントを残す
* ユーザー様やメンバーとのコミュニケーション
など、エンジニアという職業がもつイメージ以上に言葉を多く使う職業であると考えます。
その中で、「わかりやすく伝えよう」「誤解のないように伝えよう」と言葉を選びますが、
その結果伝わらなかったときにどうしても「おれがこんなに言葉を尽くしているというのにどうして伝わらないんだ」と考えたり、逆に「言葉が伝わらないのは自分の頭が悪いからだ」など自分を必要以上に責めたりしてしまうことがしばしばあります。
（僕自身相手に伝わらないとき、必要以上に自分を責めて、苦しい思いをしたことがあります）

もちろん、相手に必要な情報を伝えたり、自分の考えていることを伝える努力を怠ることをよしとするわけではありません。
相手に伝えるために「言葉」の力を磨くことは絶対に必要だと思います。

しかし、言葉というものは自身の中にある膨大な量の感情や知識を抽出したものにすぎません。
抽出されなかったものは相手には伝わりませんし、それらを抽出せずに伝えるには言葉というツールはあまりにデジタルであると思います。
（これがまさに「筆舌に尽くしがたい」というものなのだと実感しています）

なのでまずは「言葉というものは意思疎通のための重要なツールであるが、欠点も多く、
相手に伝わらないことが前提」であるという考え方を持って日々言葉の力を磨くことが
相手に自分が考えていることを伝えるための一番確かな方法であると感じました。

# 自分が役に立てたいと思った言葉
これ覚えておきたいなって特に思ったことを書いておきます。
> 語彙を増やすこと。それを使いこなすわざを身につけること。それを駆使して自分のやりたくないことをできるだけやらずに済ませる。そういうたくらみを持って、絶対に叶わない夢など追わず、きちんと手の届く目標を持ち、自分の人生に勝ち負けを持ち込まなければ、地獄は案外楽しいものです。

この考え方、エンジニアの根本にも通ずる考え方な気がします。

> 言霊は、心以外には効きませんが―――心にだけは効くんですよ。

この一節が書いてあるところ、「人間は自分がなりたいものになる」という節の中のさらに一節なんですが、ここの節は個人的にものすごい刺さりました。
こうやって自分を大事にするんだよね、って思いました。
ここは何度も何度も読み返したいところです。

# おわりに
京極さんの「言葉」を大切にしているという思いがすごく伝わってきた一冊でした。
その言葉に対する思いの深さに触れたことで、より京極夏彦さんという作家が好きになりました。
「絡新婦の理」以降の作品は読んでいなかったのですが、これを機に全巻読破したいと感じました。
また、自分もこの人のように言葉を大事にできるようになりたいと思いました。
【Unity】AssetBundleから生成したTimelineのトラックにオブジェクトを設定したい

# 【背景】

Unityで制作しているゲームで、リソースをAssetBundleダウンロードで都度読み込む仕組みで制作を進めています。

キャラクターのSpriteなどをIDを指定して動的に取得するということはできましたが、
イベントシーンもAssetBundleで読み込んでうまく動かせるのか？ということを試しました。

元々はTimeline配下に動かすオブジェクトプレハブを配置していたのですが、
AssetBundleからダウンロードしてインスタンス化してみると、
バインドが消えていたりSpriteの参照が外れていたりと思うように動いてくれませんでした。

動かすオブジェクトの方は別のAssetBundleに入っているSpriteを参照していたせいだと思い、
AssetBundleは別々でUnity上で組み立てるという方法にしました。
依存関係も一緒にまとめてくれるはずなのですが…、
AssetBundle内のアセット一覧を見るとSpriteが入っていないようでした。

最終的に苦肉の策という形になりましたが、実現できた方法を残します。

# 【実現した方法】
概要としては、以下の処理順で実現できました。

１．Timelineで使用するオブジェクトを先にシーン上にインスタンス化

２．GameObject.Findで探してきて、PlayableDirector#SetGenericBinding

３．PlayableDirector#Playで再生

# 【前提】

Timelineである程度のルールが守られていることが前提になる方法です。

- トラック名が使用するインスタンス名と一致している
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2796558/90d46d83-7de2-9dcd-8564-7d43ccad5076.png)

- シーン上に先にGameObjectが生成されている
- シーン上に同じ名前のGameObjectが存在しない
- Timeline自体の配下にバインド対象を置かない
※Canvasはセリフなどを表示するためのテキストUIです
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2796558/095307fc-ebf0-bfb7-08c9-e0af2c0929d9.png)


## 1. Timelineで使用するオブジェクトを先にシーン上にインスタンス化

１．Timelineで動かすオブジェクトは、おおよそキャラクターSpriteだったり、カメラだったりになる想定です。

キャラクターのオブジェクトはSpriteをシーン上に配置してプレハブ化しています。
これは別途AssetBundleを作成しています。一応、AssetBundleは一度ダウンロードしたら静的なリストに入れておいて、ダウンロード済み確認をして重複を避けるという方法を考えています。

別途必要なAssetBundleを何らかの方法でTimelineに必要なAssetBundleリストを取得し、
Timelineのインスタンス化の前にシーン上に生成します。

自分の場合、アセットバンドルファイルの情報をDBの保持しており、WebAPIでキャラクターIDやイベントIDに紐づくファイル名を取ってくるようにしています。
AssetBundleファイルIDもキーにしているので、イベントIDとAssetBundleファイルIDで紐づけ構成可能かもしれません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2796558/4a91064e-bbaf-b1d7-e4c8-ba675e35d6a3.png)

## ２．GameObject.Findで探してきて、PlayableDirector#SetGenericBinding

TimelineをAssetBundleから取得した後、インスタンス化する前にバインド処理を行います。

やっていることは単純で、Timelineの持つトラック名と一致するオブジェクトをシーン上から取得して、取得できていればSetGenericBindingしています。

Animation Trackとセリフ回し用のPlayabelAssetしか入っていないTimelineなので、ここではAnimation Trackのみ動的バインドしています。

``` C#
// Assetのロード
AssetBundle bundle = DownloadHandlerAssetBundle.GetContent(uwr);
var assetPrefab = bundle.LoadAssetAsync<GameObject>("EventTimeline");

yield return assetPrefab;
GameObject prefab = (GameObject)assetPrefab.asset;

 PlayableDirector playableDirector = prefab.GetComponent<PlayableDirector>();

//playableDirector内のトラック（バインド先）を取得
foreach(var bindingTarget in playableDirector.playableAsset.outputs){
    //トラック名称の一致するオブジェクトをシーンから取得してバインド
    var bindObjectName = GameObject.Find(bindingTarget.streamName);
    if (bindObjectName) {
         playableDirector.SetGenericBinding(bindingTarget.sourceObject, bindObjectName.GetComponent<Animator>());
     }
  }
```
## 3.PlayableDirector#Playで再生

バインドループを抜けたらインスタンス化するかPlayでいざ再生

```C#
  GameObject instanse = Instantiate((GameObject)assetPrefab.asset);
  //または、playableDirector.Play();
```

カメラもオブジェクトも、うまくバインドできて動いてくれました。
今度はセリフ用のUIも別AssetBundleにするかシーン内の共通UIとして
動的にPlayableAssetのクリップにバインドできるとよいかもしれません。

Spriteの依存関係や動的なTimelineのバインド方法についてはもう少し
正当な方法を探してみようと思います。

# 参考
https://tsubakit1.hateblo.jp/entry/2017/09/22/224526

https://www.ame-name.com/archives/12929
40代プログラミング初心者が考えるスキルアップする勉強方法

プログラミング初心者ならきっと使えると思う勉強方法

ただダラダラやるよりも楽しくプログラミングスキルが身につくと思います
実際に私も実践中

## 本で学習あるある コードが間違っている

初心者は本があっていると思うから、コードミスで永遠と悩んで進まなくて諦めちゃうってことあると思います！

正誤表とかあるじゃん！って思うかもしれないが、初心者はそんなの知らないし！

あと、プログラミング言語がバージョンアップしたりすると動かなくなったりする

**そこで私は思った！ コードはしっかり意味を理解しないといけない**

そして次のステップを進むことになった

## 教科書が最高のコードではない 自分でよりわかりやすく書き直す

教科書のコードは初心者にもわかりやすく書くことを意識していると思います

だからこそ、改善点はあると思います！

- 関数を使ってシンプルにしてみる
- いろんな組み込み関数を使ってみる

<B>もしかしたらこんなことできるかも？ってことを検索してみる

競技プログラミングのこーどをみてるとなんで1行で書けるの？
すごいなあぁ～って思うようになって、色々調べるようになりました

pythonだとだいたい何かしら便利な方法がある

## 勉強中だからこそ楽をせず検索すること大事

プログラミングは楽をするために、便利にするためにあると思うので、きっと世の中のプログラマーはこうやったら便利だと言う情報を発信していると思います

だから、そんなのできないって思うよりも、誰かがきっとできる用法を紹介していると思って検索する

だって、Qiitaがあるなら誰かがきっとネットに残してあるはずよ

<b>ただ写経するよりも、せっかくなら、自分ならこう書いたほうがよりわかりやすい！

って思いながら勉強したほうが、スキルアップにつながると思いますし、している気がします

そして、自分なりにコードが書けると、今成長した！！って脳汁がドバァ～って出て楽しいですよ

当たり前の内容ですが、ぜひ初心者の皆さんお互い頑張りましょう

1行にまとめすぎてわけわからなくなるのも、それもまた愛嬌
AWS Backupのバックアップジョブ失敗時に通知が届くように設定してみた。

# はじめに
こんにちは、山田です。
今回はAWS Backupバックアップジョブ失敗時に通知が届くようにする設定を下記に記載していきます。
# SNSトピック作成
SNSのコンソール画面を開き、``トピックの作成``をクリックします。
![WS000002.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1096361/7114785d-66a2-ee88-583d-e63a0a5c9a2c.jpeg)
タイプは``スタンダード``を選択して、名前を入力してトピックを作成します。
![WS000003.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1096361/deec1016-b75d-5b81-c3bd-4aa0b3fabaf8.jpeg)
SNSトピック作成後編集をクリックし、アクセスポリシーに画像の記載を追記します。
``Resource``のところは、``作成したSNSトピックのARN``を記載し保存します。
![WS000008(1).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1096361/7fb57f88-33f1-4cb8-95ae-40f573d278a9.jpeg)
# バックアップボールトの設定
次にSNSに通知が届くように、バックアップボールトの設定をしていきます。
はじめに、CloudShellをひらきます。
![WS000009.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1096361/0d027a50-6eb5-5cef-1d98-93dddbca2487.jpeg)
CloudShellを開いたら、以下のコマンドを入力します。
```
aws backup put-backup-vault-notifications --endpoint-url https://backup.ap-northeast-1.amazonaws.com --backup-vault-name バックアップボールト名 --sns-topic-arn 作成したSNSのARN --backup-vault-events BACKUP_JOB_COMPLETED
```
# SNSサブスクリプション作成
SNSのコンソール画面を開き、``サブスクリプションの作成``をクリックします。
作成したSNSトピックを選択し、プロトコルはEメールを選択し、エンドポイントには通知対象のメールアドレスを入力します。
![WS000011.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1096361/4ad303eb-058e-519a-f93d-ff6691018ff1.jpeg)
サブスクリプションフィルターの設定で、画像の記載を追記し、``Backup ジョブイベントのStateが「COMPLETED」以外``だった場合に通知が飛ぶように設定します。
追記が完了したら、サブスクリプションを作成します。
![WS000012.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1096361/f627f4dd-26d2-3e6d-1f5b-6fcac51a90a5.jpeg)
# 動作確認
AWS Backupのコンソール画面を開き、``オンデマンドバックアップを作成``をクリックします。
![WS000014.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1096361/0f82fc26-3424-dd5c-99dc-f05177016ac8.jpeg)
対象のリソース、バックアップボールトを選択しバックアップを作成します。
![WS000018.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1096361/aa2650fd-9996-5030-1814-24416e56f375.jpeg)
バックアップジョブが開始されたら、``バックアップジョブの停止``をクリックしバックアップジョブを中止させます。
![WS000019.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1096361/953b4d01-2292-7401-5fbe-bc7c04f28b5a.jpeg)
ステータスが``中止しました``と表示されたことを確認します。
![WS000022.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1096361/76476757-5bbe-4265-7398-b5379bd2b1a8.jpeg)
通知対象のメールアドレスに以下の内容のメールが届いていれば、動作確認完了です。
![WS000021.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1096361/965ad396-ee15-bef3-bfcb-fd3d4c0a7b87.jpeg)
# 終わりに
今回は、バックアップジョブ失敗時に通知が飛ぶように設定する方法を記載しました。
今回記載したことが少しでも役に立てばと思います。
終わり。
【解決法】ModuleNotFoundError: No module named 'chromedriver_binary'

- ファイル実行

```terminal
$ python3 ファイル名
```

- 失敗

```terminal:例
sample@SampleMBP Selenium % python3 sample.py
Traceback (most recent call last):
  File "/Users/username/Desktop/Selenium/sample.py", line 1, in <module>
    import chromedriver_binary
ModuleNotFoundError: No module named 'chromedriver_binary'
```

`chromedriver_binaryが見つからんぞ。`と。

# 解決までの手順


## 1. ブラウザ上でChromeのバージョンを確認

ツールバーから「GoogleChromeについて」をクリック
![スクリーンショット 2022-10-02 19.15.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2689074/c53257eb-dbb6-fc1a-a838-f85546daa4c4.png)


![スクリーンショット 2022-10-02 19.22.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2689074/3c6f422d-4d76-27c8-a493-483854786a37.png)

:::note
バージョン確認完了
:::



## 2. chromedriver-binaryをダウンロード

https://chromedriver.chromium.org/downloads

![スクリーンショット 2022-10-02 19.58.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2689074/09866f59-8a2a-7616-353d-a825df5b6b13.png)

:::note
ブラウザで確認したバージョンに一番近いバージョンを選択する。
今回の場合だと`ChromeDriver 106.0.5249.61`となる。
:::

- 下記画面に遷移するので、自身のPCに合わせてダウンロードするchromedriverのzipファイルを選択。
    - 私の場合はM1Macなので`chromedriver_mac_arm64.zip`を選択。

![スクリーンショット 2022-10-02 20.00.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2689074/eb5f7efb-e71f-4c8f-a647-00343e1cab85.png)


- zipファイルを解凍したら、実行したいファイルが格納されているディレクトリ直下に移動させる

**例**
![スクリーンショット 2022-10-02 19.48.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2689074/e3ce5b78-f9b1-dc70-d3c6-2d0a67c87e30.png)


## 3. chromedriver-binaryをインストール

- [こちら](https://pypi.org/project/chromedriver-binary/#history)からダウンロードしたchromedriver-binaryと同じバージョンを選択
    - 今回は**106.0.5249.61.0**


![スクリーンショット 2022-10-02 20.11.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2689074/1e54dc43-d7b6-f232-d9f2-d2784f2540b6.png)

- 選択先の画面でコマンドをコピーし実行


```terminal
$ pip install chromedriver-binary==106.0.5249.61.0
```

```terminal:例
(base) sample@SampleMBP Selenium % pip install chromedriver-binary==106.0.5249.61.0
Collecting chromedriver-binary==106.0.5249.61.0
  Using cached chromedriver-binary-106.0.5249.61.0.tar.gz (5.0 kB)
  Preparing metadata (setup.py) ... done
Using legacy 'setup.py install' for chromedriver-binary, since package 'wheel' is not installed.
Installing collected packages: chromedriver-binary
  Running setup.py install for chromedriver-binary ... done
```

:::note
インストール成功
:::

:::note warn
"chromedriver"は、開発元を検証できないため開けません。と出てくる場合は[こちら](https://qiita.com/rexid/items/8849e967c676a542d6c0)
:::


## 4. ファイルを実行

```terminal:例
$ python3 sample.py
```

:::note warn
実行ファイル内に文字列を出力するようなコードなどが無い場合は、何も出力されません
:::

```terminal:例
(base) sample@SampleMBP Selenium % python3 sample.py  
https://qiita.com/rexid
https://qiita.com/rexid/items/0c19ef88faeccc1c53ff                             
(base) sample@SampleMBP Selenium %
```

:::note
成功:clap:
:::
【解決法】"chromedriver"は、開発元を検証できないため開けません。

## 1. キャンセルする

![スクリーンショット 2022-10-02 19.24.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2689074/ad044737-2865-1cc0-d1f4-9b53de761f86.png)


## 2. ダウンロードしたアプリケーションの実行を許可する

- システム環境設定→セキュリティとプライバシー→「このまま許可」を押下

![スクリーンショット 2022-10-02 19.25.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2689074/e45875e1-7403-7ef1-a9de-5842c2a63e84.png)

## 3. 再度コマンドを実行し警告が出てきた時に「開く」を押下

![スクリーンショット 2022-10-02 19.26.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2689074/94d1e649-24a5-626b-14ec-d1353d245588.png)

:::note
完了
:::
PowerShell でエクセルのアドレスが何列目なのか計算する関数


コレ系のやつ何回作ってもどっかいって見つからないし、多分 $Profile のどこかにあると思うけど名前が思い出せない。

```powershell
function Split-ExcelAddress {
    param([string]$Address)

    if ($Address -match ':') { throw 1 }

    $Address = $Address -replace '\$',''

    $a = $Address -replace '[0-9]',''
    $row = $Address -replace '[a-zA-Z]',''

    $a = $a.ToUpper()

    $col = 0
    $base = 1
    for($i = $a.Length; $i -gt 0; $i--){
        $col += ([int]($a[$i-1]) - 64) * $base
        $base = $base * 26
    }

    return [pscustomobject]@{
        Row = $row
        Col = $col
    }
}
```

テスト

```powershell
Split-ExcelAddress -Address A1
# Row Col
# --- ---
# 1     1

Split-ExcelAddress -Address Z10
# Row Col
# --- ---
# 10   26

Split-ExcelAddress -Address AB13
# Row Col
# --- ---
# 13   28

Split-ExcelAddress -Address BA100
# Row Col
# --- ---
# 100  53
```

答え合わせは以下を参照した。大体あってると思う。

https://keizokuma.com/excel-rowname-rowno/
AWS SDK for JavaScript v3 で S3 バケットのオブジェクト一覧を取得する

# 初めに

認証情報を持たないユーザーが、ブラウザから S3 バケット内のオブジェクトリストを取得する方法を書きます。

# ID プールを作成する

「ID プールの管理」をクリックします。

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/37ee9073-266d-6581-9633-063938182e49.png)

「新しい ID プールの作成」をクリックします。

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/e6977355-4940-be14-bef4-53aae159e4c7.png)

ID プール名を入力し、「認証されていない ID に対してアクセスを有効にする」にチェックを入れます。

![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/30f19613-b698-125b-7215-0820cc7c2c52.png)

設定はデフォルトのまま、「許可」をクリックします。

![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/6f58e839-5e15-2412-d93c-2cf341518696.png)

「ID プールの編集」をクリックします。

![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/c0324590-5da1-af42-ddcc-7f6b62a9337e.png)

ID プールの ID、各種ロールはここで確認できます。

![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/d1cb33f6-4c98-f81a-e74a-ffe2791b063c.png)

認証されていないロール（上図緑下線）に以下のポリシーを追加します。

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket",
                "s3:GetObject"
            ],
            "Resource": [
                "arn:aws:s3:::bucket_name",
                "arn:aws:s3:::bucket_name/*"
            ]
        }
    ]
}
```

# 実装

## 準備

```
npm install @aws-sdk/client-s3
npm install @aws-sdk/credential-providers
```

## コード例

```React:App.js
import { S3Client, ListObjectsV2Command } from '@aws-sdk/client-s3';
import { fromCognitoIdentityPool } from "@aws-sdk/credential-providers";

const ListObjectByBrowser = async props => {

  const client = new S3Client({
    region: REGION, // リージョン
    credentials: fromCognitoIdentityPool({
      clientConfig: { region: REGION }, // リージョン
      identityPoolId: POOL_ID, // プール ID
    })
  });

  const command = new ListObjectsV2Command({
    Bucket: BUCKET_NAME // バケット名
  });
  const response = await client.send(command);
  console.log(response.Contents.map(x => x.Key)); // ["memo.txt", "sample.png"]
}
```

# 参考記事

https://docs.aws.amazon.com/ja_jp/sdk-for-javascript/v2/developer-guide/getting-started-browser.html#getting-started-browser-create-identity-pool

https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/clients/client-s3/classes/listobjectsv2command.html
numpy.lib.stride_tricks.as_stridedの使い方と仕組みを簡単に

# できること
numpyがサポートするndarrayオブジェクト（配列）をバイト単位で変形できる。reshapeメソッドでは形状の変更のみだが、as_stridedメソッドを使うとより手の込んだ変形ができる。

```python:
a = np.arange(10, dtype=np.float64)
b = as_strided(a, (5, 2), (8, 8))
print(a)
```
-> 
```math
\begin{pmatrix}
0 & 1 \\
1 & 2 \\
2 & 3 \\
... & ... \\
8 & 9 \\


\end{pmatrix}
```




# ライブラリの使い方

①インポート
```python:
import numpy as np
from numpy.lib.stride_tricks import as_strided
```
②メソッド呼び出し
```python:
as_strided(ndarray, shape, strides)
```

戻り値:ndarrayオブジェクト(※注意)


引数について：
ndarray→変形元のndarrayオブジェクト。例えばnp.arange(100)とか。
shape→変形後の配列の形状。ndarray.reshape()と同様に指定すればよい。例えばshape=(3,3)ならば3行3列のndarrayが返される。
strides→バイト単位でndarrayを見た時に値を参照する間隔。例えばstrides=(8,8)ならば行、列が増えるごとに8バイトずつ変形前の配列の値を読んでいく。

# 仕組み
例として以下のようなndarray配列を考える。各要素はfloat型とする。

```math
\begin{pmatrix}
0.0 & 1.0 \\
2.0 & 3.0
\end{pmatrix}
```

この時メモリ上でこの配列は次のように保存される。
0.0,1.0,2.0,3.0
これをバイトに直すと
\x00\x00\x00\x00\x00\x00\x00\x00,\x01\x00\x00\x00\x00\x00\x00\x00,\x02\x00\x00\x00\x00\x00\x00\x00,\x03\x00\x00\x00\x00\x00\x00\x00
float型は8bytesなので8*4=32bytes長となっている。

ではメモリ上のndarrayの要素にアクセスするにはどのようにしているか？
例えば、上の(2,1)要素の2.0にアクセスするならば
2x8 bytes+1x8 bytes=24 bytes目から8bytesを読み込めば良い。
この行と列の要素ごとの間隔をstrides, 1要素のバイト数をitemsizeという。上の例ならばstrides=(8,8)でitemsize=8となる。
この2要素はndarray生成時に設定される情報で、ndarray.itemsize, ndarray.stridesで確認できる。

これを踏まえた上で
as_strided(ndarray, shape, strides)
のstirdes引数が意味するのは
変形後の配列の各要素が参照する変形前の配列のバイト間隔。

例. x = (0.0, 1.0, 2.0, ... , 9.0)とする。
as_strided(x, (3,2), (16,8))とした場合、
変形後の配列の(3,2)要素にはitemsize=8とした時、
16x3 + 2x8 =64バイト目の値、つまり7.0が入る。
(1,2)要素には
16x1 + 2x8 =32バイト目の値、つまり3.0が入る


# 注意

as_stridedが返すオブジェクトは実際にはndarrayではない。元のndarrayの要素へのポインタ（参照）値をもつだけ。なので、as_stridedが返した配列の要素に代入するような操作を行うと、参照元の変形前配列の要素も同様に変更されてしまう。
ローカルリポジトリの操作について（初心者向け）

# ローカルリポジトリを操作するための流れ

gitとは分散型バージョン管理システムの一つです

- リポジトリと呼ばれる`貯蔵庫`にソースコードの変更履歴や実コードを記録します
- リポジトリにはローカル（個人端末）とリモート（共有端末）の2種が存在します
- まずはローカルにデータを保存し、最後にリモートへコードを保存します

## ローカルの基本操作

目次
1. ローカルリポジトリを初期化する
1. ローカルリポジトリへ記録する
1. ローカルリポジトリの状態を確認する
1. ローカルリポジトリの履歴を確認する
1. ローカルリポジトリの変更を元に戻す

### ① ローカルリポジトリを初期化する

プロジェクトを作成する場合、そのディレクトリを作成しますが
Gitでそのディレクトリを管理するにはGitの初期化が必要です

```console

//ターミナルでカレントディレクトリを
//プロジェクトのディレクトリに設定した後

$ git init
```

Gitの初期化をすることによりディレクトリへ
ローカルリポジトリが新規作成されます

### ② ローカルリポジトリへ記録する

ローカルリポジトリへ記録するには3つの工程が必要です

1. ワークツリー
   - リポジトリへ移す前の実際の作業環境を指します
   - 変更を加えたファイルをコマンドで指定し次のステージに移行します

    ```
    $ git　add .

     //ステージへ現在の実ファイルをアップします
     //git　add　ファイル名を指定
     // "."は全部変更しますという意味です


    $ git status

    // リポジトリで変更されたファイルを確認するコマンドです
    ```
   
1. ステージ
   - git管理内の領域になり、コミット手前の置き場になります
   - 実ファイルを変更してもステージ上のファイルは変更されません
   - ステージにアップされた内容で確実にリポジトリへコミットされます

    ```
    $ git　commit -m "コミットメッセージ"

    //　-m には変更内容をコメントで記載します
    ```


1. ローカルリポジトリ
   - 利用者の手元のコンピュータに作成されたリポジトリ（貯蔵庫）です
   - サーバー側には影響を及ぼさないため編集操作が気軽に行えます



### ③ローカルリポジトリの状態を確認する

リポジトリ、ワークツリー、ステージそれぞれの間の状態を確認するコマンドは
次のタイミングで使用します
- `git add`する前にリポジトリとワークツリーの差分をチェックする
    ```
    $ git diff
    ```
- `git　commit`する前にリポジトリとステージの差分をチェックする
    ```
    $ git diff --staged
    ```

- `git　commit`をする実行する前または後にステージの状況を確認できます
- ステージ上のファイルがコミットされていない、またはされている状況を確認
- ワークツリーからファイルをGit上に追加している、していないなどの確認
```
git status
```

### ④ ローカルリポジトリの履歴を確認する

- リポジトリは更新するにつれて変更履歴が溜まります
- 確認するためには次のコマンドを実行します
    ```
    $ git log　
    ```

### ⑤ ローカルリポジトリの変更を元に戻す

- 変更したワークツリーのコードを、コミットしていたリポジトリのコードに戻す
    ```
    $ git restore <ファイル名>　
    ```

- add（ステージにアップ）される前に戻す
- ステージに挙げた変更をワークツリーに戻す
    ```
    $ git restore --staged  <ファイル名>
    ```
【Ruby】Loggerライブラリを使用して一定期間ごとにログファイルを記録したい

# 概要
一定の期間ごとにログファイルをローテートする場合には、
引数でローテートする期間を指定する。
常にログを確認する場合一つのログファイルに書き込まれると確認が大変なため期間でログを管理すると良いと感じた。

```ruby
require 'logger'
logger = Logger.new('foo.log', 'daily') #日ごとのログ
logger = Logger.new('foo.log', 'weekly') #週ごとのログ
logger = Logger.new('foo.log', 'monthly') #月ごとのログ
```

# 参考
https://docs.ruby-lang.org/ja/latest/library/logger.html
Next.jsでボタンを押したら特定セクションまでスクロールさせたい

# 環境

- M2 Mac 12.5.1
- Node.js 16.17.1
- Next.js 12.3.1
- tailwind 3.1.8
- GoogleChrome 105.0.5195.125

# やりたいこと

ボタンを押したら特定セクションまでスクロールさせたい
見てもらった方が早いので、こんな感じ

https://webdesigner-go.com/portfolio-template-basic/

Qiitaの目次って言った方が伝わるかな？

# やりかた

## 1.スクロール先となる箇所に`id`を振っておく

一意に特定できるならidじゃなくても良いと思う

```index.tsx
<h1 id="section-profile" className="text-3xl pt-40 md:pt-20">
  Profile
</h1>
<Profile />
```

## 2.`Link`コンポーネントの`href`に`id`セレクタを指定する

```index.tsx
import Link from 'next/link'

<Link href="#section-profile">
  <a className="px-3 hover:underline decoration-c2 hover:decoration-4">Profile</a>
</Link>
```

# 注意点

ナビゲーションバーなどを`position: fixed;`で指定していると、スクロールされた後に要素が隠れてしまうので、必要に応じて`padding`を設定してやる
上記1.のサンプルコードの`pt-40 md:pt-20`はそのために指定している

# 参考

https://stackoverflow.com/questions/68589788/nextjs-link-to-scroll-to-a-section-in-same-page
Wimax端末 NEC Speed Wi-Fi 5g X11 のパケットフィルタ設定を少し楽にした

# 要約
Wimax端末NEC Speed Wi-Fi 5g X11 のパケットフィルタ設定UIがあまりに酷いので、少しだけ手間が省けるようにした

# 事の起こり（チラシの裏）
wimaxの契約更新とともに、端末を変更しました。
新機種はNEC Speed Wi-Fi 5g X11 です。
https://www.uqwimax.jp/wimax/products/nar01/

ルータなのでパケットフィルタ設定をするわけですが、このUIが酷い。
過去に触ったルータ類のなかで、ダントツ最悪です。
後継機なのに、設定画面のUI全般が先代機より猛烈に悪化してます。

画像は登録エントリ一覧画面と、新規追加画面です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282159/4ab26e78-5fb7-cee7-61ea-6f666df07975.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282159/0f7faa9f-bfc6-4a91-e6ff-de33e5413b89.png)

エントリ一覧では、削除しかできません。
登録画面で、登録済みのエントリを上書きすることもできません。
エントリを修正するには、削除してから同じ優先度での新規登録をやり直さなければいけません。
エントリ追加画面では優先度を自分で設定しなければなりません。未登録の優先度を指定しなければなりませんが、優先度はエントリ一覧画面にしか表示されません。
個人使用のルータなら「危ないポートだけ塞ぐ」が基本かと思いますが、種別（通過・破棄）のデフォルト値は「通過」です。
うっかり「破棄」にし忘れると、削除して再登録をしなければなりません。
ひとつのポートに対して、tcp in, tcp out, udp in, udp out を設定するのがお約束ですが、
 `破棄、in、TCP、any、ポート番号。` `破棄、out、TCP、any、ポート番号。` `破棄、in、UDP、any、ポート番号。` `破棄、out、UDP、any、ポート番号。` と4回登録をしなければなりません。
CSVなどによる一括登録機能もありません。

同じ機種をお持ちで設定をしようとした方は共感いただけるのではないでしょうか。

このUIでは、閉じるのが必須のポート数件ですら、間違えずに登録しきれる気がしません。

# 少しでも楽にしようその１ javascriptでpost送信
javascriptからpost送信することで自動化しようと思いました。
しかし何らかのチェックが入るのか、403が帰ってきてしまいます。一旦諦めました。

# 少しでも楽にしようその２ javascriptでフォームを編集して送信ボタンを押す
これでやりました。
Excelの設定表から、「DOMを弄って送信を押すスクリプト」を出力するVBAを書きました。
今回自分で使わない項目は未実装です。（例：TCP FLAG, ICMP, IPアドレス指定など）


設定表
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282159/74fddd22-3129-fe22-1655-93aba0cf8a3b.png)

出力するスクリプト（エントリ1件分）

```javascript
/* 種別 */
document.querySelector('input[name="Type_2_radio"][value="1"]').click();
/* 方向 */
document.querySelector('input[name="Direction_2_radio"][value="1"]').click();
/* プロトコル選択 */
document.querySelector('select[name="Protocol_select"] option[value="3"]').selected = true;
/* 送信元ipRadio */
document.querySelector('input[name="Source_IP_Address_radio_radio"][value="0"]').click();
/* 送信元portAny */
document.querySelector('input[name="Source_Port_Number_check_check"]').disabled = false;
document.querySelector('input[name="Source_Port_Number_check_check"]').checked = true;
/* 宛先IpRadio */
document.querySelector('input[name="Destination_IP_Address_radio_radio"][value="0"]').click();
/* 宛先portFrom */
document.querySelector('input[name="Destination_Port_Number_text_1"]').disabled = false;
document.querySelector('input[name="Destination_Port_Number_text_1"]').value = "2049";
/* 優先度 */
document.querySelector('input[name="Priority_2"]').value = '20';
/* 送信 */
document.getElementById('Apply_1').click();
```

# 実行
全件をまとめて実行できればよかったのですが、実際は1件送信するたびにダイアログが表示されることと、内部処理が完了しないと次の登録ができないので約10秒待つ必要がありました。（内部処理中に次を送ると、エラーが帰ってくる）
なので、1件登録するスクリプトを1行テキストで作成し、送信、10秒待ち、送信・・・の繰り返しでやりました。
実行は、chromeのコンソールからやりました。
何台もの端末に登録するのであれば、前述の「その１」の403エラーをすり抜けて一括登録できるようにしたいところですが、私物端末1台であれば許容範囲かなと思います。

# ソース
githubに置きました。
https://github.com/kumanobori/SpeedWifiX11PacketFilterHelper/blob/master/src/packetFilterSettingJsGenerator.xlsm/packetFilterJsGenerator.bas