OmniAICreator/Qiita-1.07M huggingface dataset:
【プラクティス紹介】1分でさらっと分かる「スプリントプランニング」

![scrum_e_planning.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3526800/c3f1c0ce-3093-fa6c-f0f8-fd5680877772.jpeg)


## プラクティス名（別名）
スプリントプランニング　（スプリント計画、計画ゲーム）

## プラクティスの目的・狙い
* スプリントの目的とゴールの明確化
* タスクの洗い出しと計画
* 作業量の見積もり

## どんな時に使うか
* スクラムでは必須（各スプリントの冒頭で実施する）
* スプリント作業が場当たり的に進んだり、作業量が多くて終わらない、といった事態を防止したい時

## 実施手順
1. POが今回のスプリントでしたいこととその理由を説明し、スプリントゴールを提案する
1. プロダクトバックログの中から今回対象とするアイテム（PBI）をいくつか選ぶ
1. PBIを実現するために必要なタスクを全て洗い出し、スプリントバックログに落とし込む
1. 個々のタスクは1日以内で完了する粒度まで詳細化し、作業量を見積もる

上記1.で何故（Why）を、2.で何（What）を、3～4.でどのように（How）を突き詰める。
計画段階でチームのキャパシティを超えているようであれば、持続可能なペースとは言えないので、スプリントゴールとPBIの選択を見直す。

## アレンジ例
* 時間短縮のためDEVをペアに分け、分担してタスク分解し、それを持ち寄る
* タスク洗い出し後、「完成の定義」を確認し、作業漏れがないか確認する

## アンチパターン
* タスク粒度が大きすぎて、各タスクを進捗率で管理しようとする
（→進捗はシンプルにタスクの完了/未完了だけで管理すべき）

## 参考情報
[公式スクラムガイド(2020年日本語版)](https://scrumguides.org/docs/scrumguide/v2020/2020-Scrum-Guide-Japanese.pdf)

## こぼれ話（私的コメント）
タスクを全て消化したハズなのに、いざリリースしようとすると、じゃあこれもやっておかないとね、と隠れタスクが顔を出すことがあります。これはUndoneタスクと呼ばれるもので、計画時のタスクの洗い出しが不十分だったか、完成の定義が不十分であることを意味します。またそもそもPBIを消化できたかどうかで意見が分かれる場合は受け入れ条件（AC）が不明確だった可能性があります。いずれにせよ最初から完璧な計画を立てることは難しいので、スプリントを重ねる中で精度を高めていく必要がありそうです。

　[アジャイルプラクティス一覧へ戻る](https://qiita.com/kakashi_h5/items/20584998c5ca4594b9ea)
【プラクティス紹介】1分でさらっと分かる「スプリント」

![scrum_e_sprint.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3526800/50bbfba6-dfd4-5598-e128-7e4f8ca1a763.jpeg)


## プラクティス名（別名）
スプリント　（イテレーション、タイムボックス）

## プラクティスの目的・狙い
* チーム活動に一定のリズムを生み出す
* 定期的なサイクルで回すことにより「検査」と「適応」の機会を提供する

## どんな時に使うか
* スクラムでは必須（というかアジャイル全般でほぼ必須）

## 実施手順
スクラムではスプリントの中で以下のイベント（＝定例会議）を行う。
それぞれのイベントには時間制限（＝タイムボックス）が設けられている。
タイムボックスは時間をかけすぎないための大切なルールなので必ず守る。

|スプリント期間|デイリースクラム|スプリントプランニング|スプリントレビュー|レトロスペクティブ|
|:---:|:---:|:---:|:---:|:---:|
|1週間|15分以内/日|2時間以内|1時間以内|45分以内|
|2週間|15分以内/日|4時間以内|2時間以内|1時間30分以内|
|3週間|15分以内/日|6時間以内|3時間以内|2時間15分以内|
|4週間|15分以内/日|8時間以内|4時間以内|3時間以内|

なおスプリント自体のタイムボックスは1か月以内と定められている。
スクラムイベントは毎回同じ時間と場所で行うことが推奨されているため、週単位にすることが多い。（定義の上では8日間スプリントとかでもよいが、毎回曜日がズレるためスケジュールしにくい）

## アレンジ例
* スプリントプランニングを第一部（PBI選択）と第二部（タスク分解）に分ける
（その合計時間がタイムボックスに収まっていればよい）

## アンチパターン
* チームの人数が増えたのでデイリースクラムの時間を15分から30分に拡大した
（→人数に関わらず15分以内に収まるようにやり方を工夫すべき）

## 参考情報
[公式スクラムガイド(2020年日本語版)](https://scrumguides.org/docs/scrumguide/v2020/2020-Scrum-Guide-Japanese.pdf)

なお厳密にはスクラムガイドには1か月スプリントの時間制限しか書かれておらず、スプリント期間に応じて適宜短くしましょう、となっている。そのため上記の1～3週間の時間制限は4週間の上限から逆算して記載している。

## こぼれ話（私的コメント）
スプリントの開始日を何曜日にするのがいいのかは様々な意見があるようです。月曜始まりにすると祝日が多いのでスプリント計画がリスケになりやすいとか、金曜のレトロで話したことを土日で忘れちゃう、とかとか。少なくとも会社の定例会議と被っている日は避けた方が無難ですし、結局は現場次第かな、と思います。
初心者チームだと最初のうちは全然ダイムボックス内に収まらなかったりするのですが、そこでどうしたら時間内に終わるか？と考えることに意味があるような気がします。ただレトロに関しては例外で最初のうちだけはもう少し長くやった方がいいかも、という感覚があります。消化不良で次スプリントに進むと必ずまた同じことを繰り返してしまうので。（あくまでも個人的な意見ですが）

---
　[アジャイルプラクティス一覧へ戻る](https://qiita.com/kakashi_h5/items/20584998c5ca4594b9ea)
環境構築をしたくない理由

僕は環境構築をしたくない。正しくやればすぐ終わるとは思うが、いろいろ理由があってめんどくさくなってる。理由は、以下で述べる。

# 1

一つ目の理由は、そもそもの設定が面倒くさい。

# 2

終わったと思ったら、インクルードパスやバージョンなどなどでエラーが発生して、バージョンを更新しようと思ったら、permissionがない。無理。そのせいで無駄に時間を使う。

# 3

もし環境構築が終わっても、本当に使いやすいのだろうか。僕はAtCoderに直で書く方が楽だと思っている。なぜなら、AtCoderだったら提出もすぐできるし、簡単な問題だったらライブラリを貼る必要もない。さらに、AtCoder Easy test v2があるので、テストも楽だ。


# まとめ

これに対しては色々な人の意見があると思うので、たくさん聞いてみたい。コメントよろしくお願いします。
Motionnetデバイス 基礎学習セミナー（初級）を受講したよ

日本パルスモーターのMotionnetデバイス 基礎学習セミナーを受講しました。

https://www.pulsemotor.com/event/seminar/Motionnet-seminar.html
# Motionnetとは
高速シリアル通信の規格の一つになります。
産業機器では __EtherCAT__ や __IO-Link__ などが有名で、__Motionnet__ は聞きなれないのではないでしょうか？

https://www.pulsemotor.com/products/motionnet/

__Motionnet__ は __RS485__ を拡張し６４台のデバイスを制御可能にしたものだそうで
マスター側の処理能力に依存しない上、低コストな点がメリットなようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/dbf92300-74e3-9782-f3ad-48cb7be07fae.png)

# 基礎学習セミナー
基礎学習セミナーではMotionnetスターターキットを使用します。
### Motionnetスターターキット
MotionnetスターターキットはMotionnetを試すことができるように制御基板とステッピングモーターがセットになったスターターキットになります。
![Motionnet.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/f3372101-d0f3-09e1-4c37-cd4de67b6916.jpeg)
![Motionnet2.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/77fdae9e-4290-3160-a94c-19fea4f07f1b.jpeg)
パソコンとはUSB接続でローカル側を制御できるシステムです。
特徴的なのが、USBパラレル変換によりG9001Aにつながっていることおよび、これはデメリットになりますが
Motionnetの信号線がLanケーブルではないという事です。
もし、これが汎用のLANケーブルが使えるなら利便性が高いだけに残念です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/86ee2f35-e3fc-19bc-958b-5eae4f0eb8a8.png)
引用：https://www.pulsemotor.com/download/PDF/MotionnetStarterKit/MotionnetStarterKit_Leaflet.pdf
# セミナーの様子
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/79f871f9-9bab-700b-90f3-094b8a1c653c.png)
# コントールソフト
スターターキットにはコントロールソフトが付属しておりこれにより制御可能です。
IO制御からモーションパターンの製作やモーションパターンにより制御できます。
サンプルもついており、初級セミナーを受講し、スターターキットを使うだけで一通りのことを試すことができます。
![スクリーンショット 2023-08-10 131553.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/c9efc24d-66fc-b9ee-ef06-b872c528a0fe.png)
![スクリーンショット 2023-08-10 161529.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/eb21cd6a-a7f3-de1a-cd63-4eb1bf120f85.png)
# 実使用に近づけるには
ローカル側の基板はG9002によりLEDとスイッチが、G9103によりステッピングモーターが動作します。
これらはカスケード接続されており、一通り扱えましたが、実使用ともなれば、複数のデバイスがつながっている状態を試したいところ。
中級セミナーではローカルボードを2枚使うことでこの辺りを学ぶことが可能だそうです。
Terraform導入手順(Windowws, AWSリソースを操作する想定)

**Terraform導入に必要なツール一覧**
* Python(AWS CLIのインストールにpipコマンドを使用するため)
* AWS CLI(AWSリソースの操作に必須)
* Git(tfenvの操作にGitBushが必須)
* tfenv(terraformコマンドのバージョン管理に便利なためあったほうが良い)

## 手順
**Pythonをインストール**  
* [Pythonの公式ダウンロードサイト](https://www.python.org/downloads/)から最新バージョンのインストーラをダウンロードしてくる。

* インストーラを起動。`Add Python 3.x to PATH`をチェックしてインストール。  
  チェックを忘れた場合、もう一度インストーラを起動して、アンインストールしてから再度インストールし直せばいい。

* コマンドプロンプトに`python -V`と`pip -V`を入力してそれぞれバージョン情報が出力されたらOK。

**AWS CLIのインストール**  
* pipコマンドでインストールする
  ```terminal
  pip install awscli
  ```
  コマンドプロンプトに`aws --version`を入力してバージョン情報が出力されたらOK。

* AWSへのアクセスキーを環境変数へ設定。
  ```terminal
  set AWS_ACCESS_KEY_ID=******************
  set AWS_SECRET_ACCESS_KEY=************************************
  set AWS_DEFAULT_REGION=ap-northeast-1
  ```

**Gitをインストール**  
Windowsではこのあと行う`tfenv`のインストールに必須。

* [Gitの公式ダウンロードサイト](https://gitforwindows.org/)からインストーラをダウンロードしてくる。  

* [WindowsにGitをインストールする手順](https://www.curict.com/item/60/60bfe0e.html)を参考にインストールする。  
  コマンドプロンプトに`git -v`を入力してバージョン情報が出力されたらOK。

**tfenvのインストール**  
Terrafromの複数バージョンをインストール、管理できるツール。  
Windowsでは`gitbash`でしかうまくインストール、動作しないらしいので`gitbash`を使ってインストールしていく。

* [公式リポジトリのREADME](https://github.com/tfutils/tfenv)を参考にインストールしていく。
  ```terminal
  # githubのリポジトリからクローンしてくる。
  git clone --depth=1 https://github.com/tfutils/tfenv.git ~/.tfenv

  # パスを通す
  echo 'export PATH="$HOME/.tfenv/bin:$PATH"' >> ~/.bash_profile

  # ~/.bash_profileを読み込む
  source ~/.bash_profile
  ```

* `tfenv --version`を入力してバージョン情報が出力されたらOK。

**Trraformをインストール**  
* インストールできるバージョンを確認
```terminal
tfenv list-remote
```

* インストールしたいバージョン(最新の安定板)をインストール
```terminal
tfenv install 1.5.4
```
![terraform_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1729481/95612369-bc83-ecd7-8f46-61ac7e7c7ef6.png)  
***最後の方に格納されたパスが表示されるのでメモしておく。***

* インストール済みのバージョンを確認
```terminal
tfenv list
```

* 使用するバージョンをセットアップ。バージョンを切り替える時もこのコマンドを使う
```terminal
tfenv use 1.5.4
```

**`terraform`コマンドをコマンドプロンプトなどで使いたい場合**  
現状、`gitbash`でしか`terraform`コマンドを使用できない。  
コマンドプロンプト等で使いたい場合はパスを通す必要がある。

***なお、バージョンを指定してパス設定する都合上、tfenvコマンドでTerraformのバージョンを変更してもコマンドプロンプト等で使うterraformコマンドのバージョンは切り替わってくれない。***  
tfenvコマンドで切り替えた後、以下手順で再度パスを通し直す必要がある。

* Windowsのタスクバーの検索窓に`システムの詳細設定の表示`と入力して`システムのプロパティ`を表示する。
* `環境変数`をクリックして環境変数を表示する。  
  ![env_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1729481/edbe31a7-bf7a-76fd-0a3b-2b312dea4330.png)

* `システム環境変数`の`Path`を選択して`編集`をクリックする。  
  ![env_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1729481/c14f463d-f97b-72d2-a5d3-d49fc265136a.png)

* `新規`をクリックしてTerraformの実行ファイルが置いてあるパスを入力。  
  Terraformの実行ファイルは`/c/Users/[Windowsのユーザ名]]/.tfenv/versions/1.5.4/`に格納されているはず。  
  ![env_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1729481/70e65764-1209-ff72-bc40-e580b477f53a.png)

* 今まで開いたウィンドウをすべて`OK`をクリックして閉じる。
GoogleColaboratoryで、Googleドライブのファイルにアクセスする

# 結論
Googleドライブに事前にマウントするコードを実行しておきます。
それができれば、ファイルパスを指定するときにマウントしたファイルパスを指定することでGoogleドライブのファイルにアクセスできます。

# サンプルコード
### まずはGooleドライブにマウントする
```.py
#ドライブにマウントするコード
from google.colab import drive
drive.mount('/content/drive')
```
上記のコードを実行するとアクセス許可を確認するダイアログが表示されます。
ダイアログの内容に従って許可します。

### Gooleドライブのファイルにアクセスする
```.py
# 書き込み
with open(f"/content/drive/My Drive/hogefolder/hoge.txt", "w") as f:
    f.write("hoge")
```

```.py
# 読み込み
with open(f"/content/drive/My Drive/hogefolder/hoge.txt", "r") as f:
    print(f.read())
```
```結果
hoge
```

以上です。
gitlabにSSH接続

**SSHキーを作成する**  
今回、認証方式はRSAを採用する。
```terminal
ssh-keygen -t rsa
```
SSHキーの保管場所を指定したい場合は、指定する。
```terminal
Enter file in which to save the key (/c/Users/future/.ssh/id_rsa):
```
厳重の暗号化したいなら、パスフレーズを設定する。面倒なら何も入力せずEnter2回で飛ばす。
```terminal
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
```

SSHキーの保管場所が表示されるのでメモしておく。(大体ユーザのカレントディレクトリ)  
![ssh-keygen_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1729481/e71cac72-4cdd-004a-e939-dfc10f322535.png)  

**Gitlabに公開鍵を登録**  
`自分のユーザアイコン>Prefernces>SSH Keys`の順で画面遷移。(ちょいちょいページの場所変わってるっぽいので頑張って探して)  

`Add new key`を押下。

`Key`に先ほど作成したSSHキーの公開鍵(.pub)の方の中身を貼り付ける。
![ssh-keygen_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1729481/2101c904-33d3-48d3-65d0-33ba430256f2.png)  
`Add key`を押下して登録完了。

**SSH接続準備**  
**ssh-agentに秘密鍵を登録**  
Windowsユーザは手動でssh-agentに秘密鍵を登録しないといけないらしいので登録する。

`ssh-add -l`などを入力して、以下のメッセージが出た場合、ssh-agentが起動していないので先ずはssh-agentを起動する。
```terminal
Could not open a connection to your authentication agent.
```
ssh-agentを起動。
```terminal
eval `ssh-agent`
```
ssh-agentに秘密鍵を登録する。パスはSSHキー生成時にメモしたもの。
```terminal
ssh-add /c/Users/[Windowsのユーザ名]/.ssh/id_rsa
```

**configファイルを生成**  
`公開鍵と秘密鍵が格納されているフォルダ`にホスト名、秘密鍵パス等を設定する`config`という名前(拡張子なし)のファイルを作成する。  
中身を以下のように編集する。`IdentityFile`は秘密鍵のパス。
```config
Host gitlab
    HostName gitlab.com
    User git
    IdentityFile /c/Users/[Windowsのユーザ名]/.ssh/id_rsa
```

**SSH接続テスト**  
以下コマンドを入力。初回はいろいろ表示されるが、`yes`を入力していけばOK。
```terminal
ssh -T git@gitlab
```
最終的に以下のメッセージが出ていたら接続成功。
```terminal
Welcome to GitLab, [gitlabのユーザ名]!
```

***
これでリモートからクローンしたり、プッシュしたりできるようになっているはず。  

`git clone`
```terminal
git clone git@gitlab.com:[グループ]/[プロジェクト].git
```

`git push`
```terminal
git remote add origin git@gitlab.com:[グループ]/[プロジェクト].git
git puth origin main
```
※リモートの指定には`https://...`ではなく、`git@...`の方のURLを使用する。

## おまけ
### Gitにリモート接続する際にデフォルト以外のフォルダに格納してある鍵を使用する方法
基本的にSSHキーはカレントディレクトリの`.ssh`フォルダに保存していく。  
(Linux系だと`/home/[Linuxのユーザ名]/.ssh`、Windowsだと`/c/Users/[Windowsのユーザ名]/.ssh`)  

なので、gitコマンドもデフォルトは上記パスの`.ssh`フォルダ内から鍵のパスを設定するconfigファイルや鍵を探す。  

しかし、諸々の都合上どうしてもデフォルト以外のフォルダに格納してある鍵を使用したいこともあるので以下にメモしておく。

***環境変数`GIT_SSH_COMMAND`を使用する***  
環境  
* OS: Amazon Linux 2
* Gitバージョン: 2.9.5

`home/[Linuxのユーザ名]/gitlab/.ssh`に格納してある秘密鍵を使用したい。  
ユーザのホームディレクトリで以下コマンドを叩く。
```terminal
export GIT_SSH_COMMAND="ssh -i $(pwd)/gitlab/.ssh/id_rsa -F /dev/null -o StrictHostKeyChecking=no"
```

* `-i`: 相対パスでも指定出来るが、サブモジュールの取り込み等する際に参照できなくなるため絶対パス推奨。pwdコマンドで現在位置までのパスを出力させると楽。
* `-F`: /dev/nullはconfigファイルを指定しないの意味。
* `-o StrictHostKeyChecking=no`: 初回のSSH接続の際に対話モードで確認されるやつを飛ばす。

ちなみに`git config core.sshcommand`で設定するという方法もあるそうだが、今回の環境ではうまくいかなかった。
dockerがなぜかPlease install @types/react and @types/node by runningというエラーを吐いた

docker compose upすると、なぜかタイトルのエラーが出て立ち上がらなかった。
このあたりの記事を参考にしてみたが解消せず。
https://www.techback.info/node_does_not_boot_please_install/
https://stackoverflow.com/questions/71843307/next-js-is-not-recognizing-types-react
https://zenn.dev/takeharu/scraps/d9e957bc145a9d

Dockerイメージの再構築: 依存関係が正しくインストールされていない可能性があるため、Dockerイメージを再構築してみてください。

コンテナのボリュームのクリア: Dockerのボリュームに古いデータが残っていると、依存関係が正しく認識されないことがあります。コンテナを停止し、関連するボリュームをクリアしてみてください。

```
docker system prune
docker-compose down -v //立ち上げている場合
docker-compose build --no-cache
docker-compose up
```
コードを見て学ぶ Javascript => アロー関数

## 対象・要件
* 記事タイトルの通り文章での説明はほぼしていない。
* Javascriptコードをある程度読める必要があるが、アロー関数について知りたい人なら要件はみたしているハズ。
* サンプルコードはES６仕様で記述。
* 文末等にセミコロンは不要なのでつけていない。

## 実践（各種関数の書き方からその違いを体感してみよう）

### 普通の関数/呼び出し

```JS
function hello1(name) {
  return 'Hello, ' + name + '!'
}
console.log(hello1("taro"))
```

### 無名関数を変数に代入しての呼び出し

```JS
// 無名関数を変数（const使っているけど）に代入して使用
const hello2 = function(name) {
  return 'Hello, ' + name + '!'
}
console.log(hello2("taro"))
```

### アロー関数にしての呼び出し

```JS
// アロー関数
const hello3 = (name) => {
  return 'Hello, ' + name + '!'
}
console.log(hello3("taro"))
```
※引数が１個の場合、上記例ではname部分はカッコで括られていないほうが多い気がする
const hello3 = name => {

## おまけ
### "return"文の省略(注：単文でreturnできる場合のみ有効)
```JS
// アロー関数化（"return"文の省略）
const hello4 = name => 'Hello, ' + name + '!'
console.log(hello4("taro"))
```

### 関数の引数がない場合
```JS
// 引数なし
const hello = () => 'Hello!'
console.log(hello())
```

### 関数の引数が引数２個（以上）の場合
```JS
// 引数２個（以上）
const helloS = (name1, name2) => 'Hello, ' + name1 + ' and ' + name2
console.log(helloS("taro", "hanako"))
```
ドローンの国家資格取得の流れ(二等無人航空機操縦士)

# はじめに
先日ドローンスクール経由でドローンの免許を取得したので記録に残します。
今回取得したのは一番グレードの低いものとなります。

# かかった日数
全体で2か月程度かかりました。
特に学科試験合格後の手続きに時間がかかりましたので、必要な方は余裕をもったスケジューリングをお勧めします。

# 費用について
教習所経由の場合、経験者と未経験者で費用が違います。
ドローン経験者の場合20万程度、未経験者の場合は40万程度となります。

# 取得までの流れ
自動車の免許と同じで、教習所経由と免許センターで一発試験のルートがあります。
教習所(ドローンスクール)経由のルートの場合、
1. 教習所で学科、実技講習
1. 教習所で実技試験
1. テストセンターで学科試験
1. オンラインで免許申請
1. 郵送で免許証送付

となります。

### 教習所で学科、実技講習
事前にオンラインで学科講習を受けた後、現地でドローンを飛ばします。
体調に気を付けることが大事です。
### 教習所で実技試験
教官立会いの下実技試験を実施します。
天候に左右されるところもありますので祈りましょう
### テストセンターで学科試験
テストセンターを予約し、CBT形式のテストを受けます。
首都圏だとお茶の水のテストセンターしか空きがありませんでした。

### オンラインで免許申請
[ClassNK](https://ua-remote-pilot-exam.manaable.com/top)っていうサイトで免許申請を実施します。
申請に一部お金がかかります。

### 郵送で免許証送付
オンラインの申請が完了したら、後は免許が届くのを待つだけです。
結構かかりますので気長に待ちましょう

# 今回利用した教習所について
今回私が利用した教習所は、秋葉原にある[田中電気様](https://drone.tanaka-denki.co.jp/)となります。
スタッフの方の対応がとても丁寧でしたので、個人的にはお勧めできます。
また、一番上のグレード(一等無人航空機操縦士)の合格者を最初に出している実績もありますので、次も利用しようかなと思います。
cdコマンド備忘ログ

# cdコマンド備忘録
[]かっこはつけない
#### 普通に移動
相対パス、絶対パスどちらでも
```
cd [ディレクトリ]
```
#### ホームディレクトリ（ログイン時に表示されるディレクトリ）に移動
```
cd /
```

#### ルートディレクトリに移動
```
cd %homepath%
```
linuxだと`cd ~`(チルダ)
#### おまけ
`cd ^`と入力すると`More?`と聞かれるのでディレクトリ名を入力すると移動できる
(^は英語でcaretというのですが、Googleで検索しても全くヒットしなかったです。)
Warning : `load_model` does not return WordVectorModel or SupervisedModel any more, but a `FastText` object which is very similar. への対処方法

# 警告の意味
Githubの[issues](https://github.com/facebookresearch/fastText/issues/1056)の内容を参考にすると、単にload_modelの使用が非推奨であることを伝えているだけで、気にする必要はないようである。

# 警告を消したい
警告をなくしたい場合、以下のように書くことで解決できる。
```
from fasttext.FastText import _FastText
fasttext_model = _FastText(model_path=fasttext_model_path) #fastext.load_model(path)の代わり
```
"_"がついているクラスを直接読んでいるためあまり推奨はされないが、fasttext.load_modelの実装は以下に示すようにprintで必ずWarningを出した上で、_FastTextクラスのインスタンスをreturnしているだけである。そのため、Warningを消したい場合、_FastTextクラスのインスタンスを直接作り出すしかないと考えられる。
```
def load_model(path):
    """Load a model given a filepath and return a model object."""
    eprint("Warning : `load_model` does not return WordVectorModel or SupervisedModel any more, but a `FastText` object which is very similar.")
    return _FastText(model_path=path)
```
Hardhatでプロジェクトを作成するまで(2023/08/15)

こちらの記事は[HardhatのTutorial](https://hardhat.org/tutorial/)の日本語解説となります。

Web3の勉強をしたいと思ってチュートリアルの日本語記事を探していたのですが、Hardhatのチュートリアル記事ってあんまりないのですね、、、qiitaで調べてみても2,3件しかありませんでした。
先人たちの記事はこちら👇
[Hardhatのチュートリアルをやってみた](https://qiita.com/koffee0522/items/daff22907b6e6ce89e13)
[【Solidity】HardhatでDappを作ってみる ~ チュートリアル編（前半）~](https://qiita.com/yuskey/items/0722271dc88b637330f2)
先人たちの解説があるのですが、改めてチュートリアルの日本語Verを作成しました。

# Hardhatとは
+ ローカルでSolidityを実行可能。
+ 開発専用のEthereumネットワーク、Hardhat Networkの提供。
+ デバッグに特化し、エラー時の詳細な情報提供。
+ 高い柔軟性とカスタマイズ可能性。
+ 既存のツールとの統合が容易。
+ 完全に拡張可能で、プロジェクト固有のニーズに対応。
+ プラグインエコシステムを有し、機能追加やツールの統合をサポート。
+ 開発フィードバックループの高速化。
+ TypeScriptのネイティブサポートによるミス検出能力の強化。

公式：https://hardhat.org/

# チュートリアル開始
## 1. 環境を整える
Node.jsをインストールします。Node.jsがインストールされている方は飛ばしちゃってください。インストールしたことが無い方は「Node.js インストール方法 Mac」などで検索して、出てきた記事を参考にインストールしてください。
参考：[【Windows/Mac/Linux（Ubuntu）】Node.jsインストール方法](https://qiita.com/ryome/items/eec08b28aff294e8c3d6)
[Hardhatのチュートリアル](https://hardhat.org/tutorial/setting-up-the-environment)ではバージョン20.~のNode.jsが推奨されています。

## 2. 新しい[Hardhatのプロジェクトを作成](https://hardhat.org/tutorial/creating-a-new-hardhat-project)する
### １. ディレクトリの作成と移動
ターミナルを開いて、以下のコマンドを実行する。(hardhat-tutorialディレクトリを作成し、作成したディレクトリに移動します。)
```
$ mkdir hardhat-tutorial
$ cd hardhat-tutorial
```
### ２. package.jsonの作成と、hardhatをインストールする。
```
$ npm init -y
$ npm install --save-dev hardhat
```
### ３. npx hardhatを実行し、hardhat.config.jsを生成する。
自分がhardhat-tutorialディレクトリにいることを確認したら、npx hardhatを実行します。実行後にHardhatと、? What do you want to do? … という選択肢が表示されるので、3つ目のCreate an empty hardhat.config.jsを選択してください。
```
$ npx hardhat
888    888                      888 888               888
888    888                      888 888               888
888    888                      888 888               888
8888888888  8888b.  888d888 .d88888 88888b.   8888b.  888888
888    888     "88b 888P"  d88" 888 888 "88b     "88b 888
888    888 .d888888 888    888  888 888  888 .d888888 888
888    888 888  888 888    Y88b 888 888  888 888  888 Y88b.
888    888 "Y888888 888     "Y88888 888  888 "Y888888  "Y888

Welcome to Hardhat v2.0.0

? What do you want to do? …
  Create a sample project
❯ Create an empty hardhat.config.js
  Quit
```

### ４. プラグインのインストール
スマートコンラクトを開発する上で必要とするものが全てが揃うプラグインをインストールします。
warningがたくさん出ますが、無視します。
```
$ npm install --save-dev @nomicfoundation/hardhat-toolbox
```
プラグインのインストールが終わったら、hardhat.config.jsに```require("@nomicfoundation/hardhat-toolbox");```を追加します。
```
require("@nomicfoundation/hardhat-toolbox");

/** @type import('hardhat/config').HardhatUserConfig */
module.exports = {
  solidity: "0.8.19",
};
```
以上で環境設定は完了です！

次は[スマートコントラクトの作成とコンパイル](https://hardhat.org/tutorial/writing-and-compiling-contracts)を解説したいと思います。

<参考>
[npm initする理由](https://chat.openai.com/share/196aac64-75c3-43e1-baba-c262556d9d04)
[npm init -yで-yを付ける理由](https://chat.openai.com/share/16cebab9-9918-4b48-99a8-349d4b03810f)
[--save-devの意味は何ですか？](https://chat.openai.com/share/f68867e1-68b3-45f9-9ec0-dfed3cd815f1)

👇の記事を参考に英語を読みました。
[3年かけてたどり着いた英語記事を読むための方法](https://qiita.com/tomoyamachi/items/cdb2ccb78c6c9651e0ab)
来春から新卒エンジニアになる大学生のぼやき

# 初めに
こんにちは！ IT企業から内定をいただいた情報学部の大学生です。
卒業制作ではGitHubの使い方をまとめて、資料を作って授業をしています。
プログラムは以下の基本構文が使える程度です。

- C++
- C#
- C
- Java
- Python

discordのしょぼいbot作り、Unityを使ったゲーム作りくらいの経験があります。
来年からエンジニアになるので、今の気持ちを残していこうと思います。
ただの大学生のぼやきだと思ってください笑

# 楽しみなこと

### お金が貯まる
とにかくこれが超嬉しいです。1時間980円でレジをする必要がなくなります。欲しい物も買える範囲が広がるでしょう。何より、奨学金の不安を解消できます。私はどうぶつの森で家のローンを何よりも優先して支払うタイプの子供でした。しばらくは借金返済に全力を注ぎます。

### 一人暮らしできるかも？
これも地味に楽しみです。一人暮らししている友達に言うといつも怒られますが、憧れるものなんです。
自分の部屋を趣味のもので埋め尽くしたいのです。

# 不安なこと

### 大学で学んだことを活かせるのか
そもそも大学で学んだことは通用するのか、自分が社会人としてやっていけるのか。心配で仕方がありません。

ただ、大学の友人も同じように見えるのでそんなものかもしれないです。なるようになるとどっしり構えられる人が強いのかもしれません。~~私にはできません。~~

### 同期が格上に見える
内定者懇親会に行った時に、話す人全員が格上に見えてしまいます。卒業制作でドローンを飛ばすプログラムを書いている人、競技プログラミングの順位が超高い人。とんでもないです。
対抗して、私は筋トレで物理的に強くなるように頑張っています。

研修で無能だと思われたくはない。

 ### 研修
1つ上の先輩の成果発表会を聞く機会があった時に、私よりも断然上手くスピーチできていることが印象に残りました。
緊張すると腹痛が起きる私が、１年後にあんなに上手く人前でスピーチできる気がしません。
こればっかりは数をこなすしかないのか。人前に立つ機会も多くなる社会人生活一番の不安です。

# まとめ
やっぱり不安なことの方が多いことが記事を書いてて分かりました。新しい環境に出る前なら、みんなそう言うものですよね。ポジティブに捉えておきます。
私はとにかくお金を稼ぎたいです。そのためなら転職でもなんでもするつもりです。
この記事を1年後、５年後、10年後と読んで黒歴史ではなく、誇れるような社会人になりたいです。
頑張れ！未来の俺！
初めてのSwift標準入力の受け取り方編！(!を使う理由調べてみた)

# Swiftをやる目的
・エンジニアになりたいきっかけが手持ちの洋服を管理できるアプリを作りたいと思ったから。
・iPhoneユーザーなので端末に自分のアプリがあればモチベが上がると思ったから。
・アプリを開発できれば、就活に活かせるポートフォリオを用意できると思ったから。

# ”let”と”var”の変数の使い分け
```
    - var（Variable　- 意味/変数）
        - 再代入可能
    - let(let it beのlet説 - 意味/そのままにしておく)
        - 再代入不可
```
# Swiftの標準入力の受け取り方-文字列-
```swift
let name = readLine()!
print("Hello \(name)")
```
<b>標準入力</b>
World
<b>標準出力</b>
Hello World

# Swiftの標準入力の受け取り方-整数-
```swift
var number = Int(readLine()!)!
print(number)
number = 100
print(number)
```
<b>標準入力</b>
1
<b>標準出力</b>
1
100
・letを使って再代入した時のコンパイルエラーの例
```swift
let number = Int(readLine()!)!
print(number)
number = 100
print(number)
```
<b>標準入力</b>
1
<b>標準出力</b>
Main.swift:3:1: error: cannot assign to value: 'number' is a 'let' constant
number = 100
^~~~~~
Main.swift:1:1: note: change 'let' to 'var' to make it mutable
let number = Int(readLine()!)!
^~~
var
# Swiftの ! (ここ更新するかも)
<b>結果</b>
・Swiftの ! はオプショナル型の値を取り出す記号で、変数から値（文字や数字）を取り出すときに必要な演算子。
・変数に値が入っていないと予期せぬ値が入り込んで安全に変数を使うことができないから！が必要。

<b>理解までの道のり</b>
・Swiftの ! は、アンラップ演算子（Unwrapping Operator）という。
・アンラップ演算子はオプショナル型（Optional）から値を取り出すために使用される。
・オプショナル型は、値が存在するかどうか不確かな状態を表すからそのままでは値を使用することができない。
・アンラップ演算子を使うことで、オプショナル型の値を安全に取り出して使用することができる。
・アンラップ演算子をオプショナル型の変数やプロパティの後に置くことで、その値が存在することが確定している場合に値を取り出すことができる。
・オプショナル型の値が nil（存在しないことを表す特殊な値）だった場合、アンラップ時にランタイムエラーが発生する可能性があるため、アンラップする前に必ず値が存在するかどうかを確認する必要がある。
Railway で Discord bot + Postgres を運用する

## Railway とは
[Railway](https://railway.app/) は PaaS (Platform as a Service) のひとつで、似たサービスに Heroku がよく挙げられます。Heroku の有償化に伴って Railway を知ったという方も多いのではないでしょうか。
ここに Discord bot をホスティングして動かそうじゃないか、というお話です。
今回はそこに DB として Postgres を用意する形にします。

## 前準備
- Railway へのログインは GitHub 連携で行うことができます。
メールアドレスでアカウントを作成することもできますが、コード管理に GitHub を利用していることを前提として進めます。
    1. [Railway](https://railway.app/) にアクセスする
    1. 右上の "Login" をクリックする
    1. Github のアカウントからサインイン

- Discord bot の用意
こちらの記事を参考にし Python で実行する bot を作成します。
[Python で Discord Bot を起動する](https://qiita.com/kunakori/items/f862b7d2e70e03709f5c)

## Railway で bot を実行する
1. `requirements.txt` を用意する
ここでは bot に必要なモジュールを記載してあげます。このあと用意する `Dockerfile` に必要となります。
バージョンについては適宜変更・更新を行なってください。また、利用するライブラリはお好きなもので構いません。
    ```text:requirements.txt
    discord.py==2.3.2
    python-dotenv==1.0.0
    psycopg2==2.9.7
    ```
    - discord.py
        - Python 用 Discord API ラッパー
    - python-dotenv
        - 環境変数の読み込みのためのライブラリ。DB 周りで利用します。
    - psycopg2
        - PostgreSQL データベースアダプタ。Python から PostgreSQL へアクセスするためのライブラリ。

1. `Dockerfile` を用意する
リポジトリに `Dockerfile` があれば、Railway でそれを検知し、コンテナアプリケーションとして Python ファイルを実行することができます。
    ```Dockerfile:Dockerfile
    FROM python:3    
    WORKDIR /environment

    RUN apt-get update
    RUN pip install --upgrade pip
    
    COPY ./requirements.txt requirements.txt
    RUN pip install -r requirements.txt
    
    COPY . /environment
    CMD python sample_bot.py
    ```

    [前準備](#前準備) で用意した bot は `sample_bot.py` を実行することで動いています。そのため `Dockerfile` の最後の行での記載もそれに合わせておきます。

1. Railway からデプロイする
以上のファイルが揃ったリポジトリを Railway で選択することでデプロイはできてしまいます。そもそものリポジトリの選択や、ブランチを間違えないように気をつけましょう。
デフォルトの設定だと、ブランチに変更があった場合、自動的に再デプロイを行なってくれるようになっています。

## Postgres を用意 & bot 側からの接続
1. Railway に Postgres を配置
    - Railway の Dashboard から "+ New" をクリック
    - Database から "Add PostgreSQL" をクリック
    これだけ。

1. Python から Postgres に接続するためのソースの用意
今回は psycopg2 を利用します。記法は以下の通りですが、接続に必要となる情報を dotenv で環境変数から取るようにしています。

    ```python
    from dotenv import load_dotenv
    import os
    import psycopg2
    
    # postgreSQL 接続情報
    load_dotenv()
    connection = psycopg2.connect(
        host=os.environ.get("DB_HOST"),
        port=os.environ.get("DB_PORT"),
        database=os.environ.get("DB_NAME"),
        user=os.environ.get("DB_USER"),
        password=os.environ.get("DB_PASSWORD"),
    )
    ```

1. 環境変数の設定
値の設定は Railway で行います。実際に値を設定するのは、Dashboard からデプロイした GitHub のリポジトリを選択し、"Variables" タブに追加していきます。
    - `DB_HOST`: `PGHOST`
    - `DB_PORT`: `PGPORT`
    - `DB_NAME`: `PGDATABASE`
    - `DB_USER`: `PGUSER`
    - `DB_PASSWORD`: `PGPASSWORD`
PG から始まる値は実際の設定値です。これらは Dashboard の Postgres → Connect → Available Variables に記載があります。

以上で Postgres に bot 側からアクセスするための設定が完了します。
テーブルやデータの追加は Railway 上から行うことができますし、ここで使用した接続情報を利用すれば、例えば pgAdmin などの GUI 管理ツールからアクセスすることも可能です。
Oracle Cloud Infrastructure Architect Associate 勉強メモ（NoSQL DataBase Service）

# 概要
**カラムナー型**と呼ばれる列志向のDB（反対は行志向のリレーショナルデータベース）や**キー・バリュー型**（その名の通りキーと値で格納する。連想配列のようなイメージ？）、**ドキュメント型**（JSONやXML形式で記述されたドキュメントの形で管理するモデル）のデータモデルを利用可能。
以下のリンクがとてもわかりやすい。
https://qiita.com/toshi_machine/items/13b0c3b444f6344e004c
最新SSD・機械学習による**高パフォーマンス・高信頼性のフルマネージド**なNoSQLデータベースサービス。
RDB（リレーショナル・データベース）と違い、複数のサーバーに分散して処理が可能。**安定した低レイテンシ**を実現。
テーブル単位でプロビジョニングし、**容量やリクエストベースによる課金体系**
APIとSQL双方に対応した容易なデータアクセスが可能。
ACIDに対応。
**クロスリージョン**なサービスで**マルチ・リージョンテーブル**を作成可能。
各リージョンにDBのコピーを配置、自動で同期を行い耐障害性にそなえる。
ストレージ容量はテーブルレベルごとに管理。
Enterprise Editionであれば、オンプレミスのデータセンター、Oracle CloudへのBYOL、またはその他のクラウド・ベンダーに導入可能
スループット容量は書き込み単位や読み取り単位で計測。
一瞬で理解！JavaScriptの`debounce`テクニックとその実装方法

あなたがウェブサイトやアプリケーションを開発しているとき、高頻度で発火するイベントにどう対応すればよいか考えたことはありますか？この記事では、その問題を解決するための`debounce`テクニックについて紹介します！

## 目次
1. `debounce`とは？
2. `debounce`のメリット
3. JavaScriptでの`debounce`の実装
4. 使用例と応用
5. まとめ

---

## 1. `debounce`とは？

`debounce`は、高頻度で発火するイベント（例: ウィンドウのリサイズ、キー入力など）を制御するためのテクニックの一つです。このテクニックを使うと、特定の時間間隔内に再度イベントが発火しなかった場合にのみ関数を実行することができます。

---

## 2. `debounce`のメリット

- **パフォーマンスの向上**: 不要な関数の実行を抑制することで、アプリケーションのパフォーマンスを向上させることができます。
- **APIのコスト削減**: ユーザーの入力ごとにAPIを呼び出すのを防ぐことで、APIのリクエスト回数を減少させることができます。
- **ユーザーエクスペリエンスの向上**: イベントの高頻度発火による不要な動作やアニメーションを避けることで、よりスムーズなユーザーエクスペリエンスを提供できます。

---

## 3. JavaScriptでの`debounce`の実装

以下は、JavaScriptでの`debounce`関数の実装例です。

```javascript
function debounce(func, wait) {
    let timeout;
    return function(...args) {
        const context = this;
        clearTimeout(timeout);
        timeout = setTimeout(() => {
            func.apply(context, args);
        }, wait);
    };
}
```

---

## 4. 使用例と応用

### 4.1 ウィンドウのリサイズイベント

ウィンドウのリサイズイベントが高頻度で発火するのを防ぐ例です。

```javascript
const debouncedFunction = debounce(() => {
    console.log('Debounced!');
}, 300);

window.addEventListener('resize', debouncedFunction);
```

この実装により、ウィンドウがリサイズされたときに300ミリ秒間何も発火しなかった場合のみ、`console.log('Debounced!');`が実行されます。

### 4.2 入力フォームとAPIリクエスト

ユーザーがテキスト入力をするたびにAPIリクエストを送るのを防ぐ例です。

```javascript
const debouncedSearch = debounce((query) => {
    fetch(`https://api.example.com/search?q=${query}`)
        .then(response => response.json())
        .then(data => {
            // 結果の表示や処理
        });
}, 500);

document.querySelector('#search-input').addEventListener('input', (e) => {
    debouncedSearch(e.target.value);
});
```

---

## 5. まとめ

`debounce`は、高頻度で発火するイベントを制御するための非常に有用なテクニックです。このテクニックを活用することで、アプリケーションのパフォーマンスを向上させたり、ユーザーエクスペリエンスを向上させることができます。是非、あなたのプロジェクトにも取り入れてみてください！

---

以上、`debounce`テクニックについての解説でした。この記事が役立ったら、いいねやコメントをお願いします！

---
【自己紹介】Hello "Qiita world"！

# はじめに
ついにQiitaへ初投稿です！:raised_hands:
以前は会社の技術ブログで記事を書いていましたが、転職を機にQiitaデビューすることにしました！
以前からQiitaは気になっていたので、ようやく重い腰を上げることができました。

# 自己紹介
初めまして、ミヤウチです！
2018年4月からプログラマーとして社会人デビューし、現在は社会人歴6年目になります。
2023年6月までは沖縄県の某IT企業で勤務し、同年7月からは東京都内の某IT企業に勤務しています。
（現職の会社はプロフィールに設定しているので、隠すまでも無いですが...:sweat_smile:）
細かいことはさておき、私自身のスキル（技術経験や保有資格）は以下の通りです。

#### 経験のある技術
 - 仕事（前職）： Java、PHP（Phalcon）、Python、SVN、Flutter、IoT（主にラズパイ）、AWS、Firebase ...etc
 - 仕事（現職）： PHP（Laravel）、Typescript、Git、Docker、GCP ...etc

#### 保有資格 （ 取得年 ： 資格名で記載 ）
 - 2017年 ： ITパスポート、基本情報技術者（いずれも大学4年の時間がある時に勉強して取得）
 - 2020年 ： AI実装検定（A級）、JDLA Deep Learning for GENERAL
 - 2021年 ： AWS Certified Cloud Practitioner ・ Developer Associate
 - 2023年 ： AWS Certified Solutions Architect Associate/Professional ・ SysOps Administrator Associate

思い出せる範囲になりますが、現時点での経験や資格についてはこんな感じです。
一言で言えば、「色んな開発に関わること、勉強することが大好きなエンジニア」です。
Developer Associateが来年4月に有効期限を迎えてしまうので、現在はDevOps Engineer Professionalの取得に向けて勉強をしています。

大学の在籍当初は教員を目指していたこともあり、名前を覚えることや指導することが得意です。
この特性を活かして、前職では在籍2年目からOJT（新人研修）のトレーナーを担当し、課題の作成も行っていました。
（今はSEをやっていますが、数学（中学・高校）の教員免許は取得して卒業しました。）

# 目的
Qiitaへの投稿は「技術を活用した手順や開発内容の備忘、共有、アウトプット（理解の確認）」を目的にしています。
できる限り分かりやすく、見ていただいた方にとって参考になるような記事を目指したいと思います。
ただ、ハードルを上げすぎるのも良くない（書くのが嫌になる、ネタが思いつかなくなる）ので、気軽に記事を書いていきます。
（フィードバックを貰えたら大喜びします:bow_tone1:）

# 今後の予定
保有資格を見ていただいて分かる通り、私はAWSに関心を持っている1人です:sunglasses:
そのため、記事で取り上げる技術はAWSがメインになると思いますが、特に縛りは設けず、試したことは取り上げたいと思います。
面白い技術、サービス等ありましたら教えてください！

# おわりに
更新の頻度はあまり高く無いかもしれませんが、コツコツ頑張りますのでどうぞよろしくお願いします。
特にノルマは設けず、よんな〜よんな〜[^1] やっていきたいと思います。
それでは、次回の記事で会いましょう:wave:


[^1]:沖縄の方言で「のんびり、マイペースで」という意味です。
Node.js Expressのルート（routes）を一覧表示するライブラリを作った話

## はじめに

以前、（所属する会社の）ブログで書いた[【Node.js】Expressでroutesの一覧を成形してログ出力してみた](https://note.com/shift_tech/n/ne1c160a36aa9)でやった、Expressに登録済みのルーティング（routes）を一覧でログに出力する機能をライブラリにしてみた。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1372684/bdbd8215-c83d-ade6-7535-79769ba388de.png)

今回は、そのライブラリ（パッケージ）を開発した際の

- TypeScriptをあきらめてJavaScriptで開発したこと
- ES Moduleで開発をしつつも、CommonJSでもパッケージを公開したこと

などを記事にしたいと思う。

※公開したパッケージは以下。

https://www.npmjs.com/package/console-express-routes?activeTab=readme

## TypeScriptをあきらめた理由

これは[実装](https://github.com/yutak23/console-express-routes/blob/main/index.js#L60)を見ていただければわかる通りで、Expressの型定義で`any`で定義されている`app._router`の中のプロパティにアクセスして実装する必要があるため。

https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/express-serve-static-core/index.d.ts#L1257

```ts
export interface Application<
    LocalsObj extends Record<string, any> = Record<string, any>
> extends EventEmitter, IRouter, Express.Application {
    ...
    /**
     * Used to get all registered routes in Express Application
     */
    _router: any;
    ...
}
```

最初は頑張ってTypeScriptで実装しようと思ったが、型の恩恵のあるコードでもなく開発しているライブラリの関数の型定義自体はすごくシンプルなので`tsc`コマンドで型を作成するまでもないという判断で、JavaScriptで実装した。

## ES Moduleで開発をしつつも、CommonJSでもパッケージを公開する

Node.jsでも`"type": "module"`でES Moduleを利用して開発ができるようになった今、あえてCommonJSで開発する理由はないと思ったので、今回開発したパッケージもES Moduleで開発は行った。

ただ、とはいえ現時点でES ModuleではなくCommonJSでプロダクトコードを書いている方もいると思うので、パッケージとして公開する際は、CommonJS・ES Moduleの両方に対応したデュアルパッケージとして公開することにした。

方法は昔、Node.jsでES Moduleで開発をする際に行われていたBabelでトランスパイルをするという方法と同じ。つまり、BabelでES ModuleをCommonJSのJavaScriptに変換する方法をとった。具体的には、以下のようなBabelの設定をした上で、以下のようなコマンドでトランスパイルを行う。

```js:babel.config.cjs
module.exports = {
	presets: [['@babel/preset-env', { targets: { node: 16 } }]]
};
```
```console
$ babel index.js --out-dir cjs && echo '{\"type\":\"commonjs\"}' > cjs/package.json
```

上記のトランスパイルのためのコマンドで、`echo '{\"type\":\"commonjs\"}' > cjs/package.json`を実行してpackage.jsonを新しく作成しているが、これは[Dual package hazard](https://nodejs.org/api/packages.html#dual-package-hazard)に書かれている方法でES ModuleとCommonJSを共存させるために行っている。

※デュアルパッケージとして公開する場合には、以下のようにpackage.jsonで公開するコードの設定も追加で必要になるので注意。
```json:package.json
{
	...
	"types": "./index.d.ts",
	"main": "./cjs/index.js",
	"module": "./index.js",
	"exports": {
		".": {
			"types": "./index.d.ts",
			"import": "./index.js",
			"require": "./cjs/index.js"
		}
	},
	...
}
```

- 参考：https://github.com/microsoft/TypeScript/issues/49462#issuecomment-1633279027
【flutter】Widgetを横並びにするには？

こんにちは。
今回は、Widgetを横並びにする方法を紹介します。

# 方法
![スクリーンショット 2023-08-13 20.18.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524120/ce57fee2-1687-ea40-8538-b4c8b9db94e0.png)

横並びにするには、「Row」のウィジェットを使います。



# 使用例
```dart
Row(
          children: [
            Text("文字"),
            Icon(Icons.favorite),//❤️のアイコン
            Text("よこ"),
            Icon(Icons.sports_baseball),//⚾️のアイコン
            Text("yoko"),
          ],
        )
```

# 実行例
![スクリーンショット 2023-08-15 15.06.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524120/26effb06-19bb-8cf3-b3b7-df4423e060c3.png)
IntelliJ IDEA / WebStorm + ts-jestで "File is not included in any tsconfig.json"

## 先に結論だけ

表題のエラーが出た場合、ts-jest用の単体テストファイルが配置してあるディレクトリに新たなtsconfig.jsonを追加し、includeとexcludeフィールドを上書きします。

*▼__test__/tsconfig.json*

```json
{
  "extends": "../tsconfig.json",
  "include": ["./", "../src"],
  "exclude": []
}
```

## はじめに

この記事は、IntelliJ IDEA系列のIDEでts-jest用のファイルに警告が発生する問題を記録、共有するためのものです。

### 想定する読者

- IntelliJ IDEA系列のIDEを使っている
- ts-jestを使っている
- 単体テストファイルをTypeScriptで書いている

:::note warn
この問題はIntelliJ IDEA系列のIDE固有のものです。
:::

### 想定する環境

- WebStorm 2023.2
- TypeScript 5.1.6
- jest 29.5.0
- ts-jest 29.1.0

:::note warn
対象となるアプリやパッケージのバージョンが変わると、記事の内容がそのまま適用できないかもしれません。記事を読む前に、お手元の環境をご確認ください。
:::

## 問題と再現方法

プロジェクトにTypeScriptとts-jestをインストールします。

```bash
npm install --save-dev jest typescript ts-jest @types/jest
```

プロジェクトのルートディレクトリにtsconfig.jsonを配置します。

```json
{
  "compilerOptions": {
    "baseUrl": "./",
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "__test__"]
}
```

`__test__`ディレクトリを作成し、`test.spec.ts`を配置します。

![問題ウィンドウの表示](https://www.evernote.com/shard/s9/sh/8043005c-b7c2-4ca1-8e25-feb6571810e6/jOuHC588ZyYsHM1ZDksbllnw_YihMSiOglKePETKRw11HHFiVtUCk6As1w/deep/0/image.png)

この段階で`問題`ウィンドウに`File is not included in any tsconfig.json`という警告が表示されます。警告が表示されるだけで、ts-jestの単体テストは正常に完了します。

## 解決方法

この警告は単体テストの動作には影響しませんが、問題ウィンドウの見通しが悪くなります。警告が表示されないように設定ファイルを追加します。

### 問題の原因

この問題は、tsconfig.jsonの設定で

- テストファイルが`include`の範囲から外れている
- テストファイルが`exclude`で除外されている

のいずれかで発生します。

上記の再現例では

- `src`ディレクトリだけをincludeしている
- `__test__`ディレクトリをexcludeしている

ために`__test__/test.spec.ts`がtsconfigの対象外になっています。
### IntelliJ IDEAのエラーチェック

IntelliJ IDEA系統のIDEやVisual Studio Codeは、編集中のTypeScriptファイルからもっとも近いtsconfig.jsonを参照してエラーをチェックしています。

https://intellij-support.jetbrains.com/hc/en-us/community/posts/360003428920-Can-t-disable-typescript-inspection

この動作は、tscコマンドの動作にしたがっています。tscコマンドを`--project`オプションなしで実行した場合、TypeScriptコンパイラーはディレクトリを遡ってもっとも近いtsconfig.jsonを探します。

https://www.typescriptlang.org/docs/handbook/compiler-options.html

IntelliJ IDEA系統のIDEはこの動作に従い、単体テストファイルをチェックします。単体テストファイルがincludeもしくはexcludeの範囲に入っていないため、tscコマンドを実行してもトランスパイルされないという警告を表示します。Visual Studio Codeも同じようにエラーをチェックしていますが、この件については警告を表示しません。

### テストディレクトリにtsconfig.jsonを追加する

ts-jestで利用する`__test__`ディレクトリー内のエラーのみを修正したい場合、このディレクトリに新たなtsconfig.jsonを追加します。

```json
{
  "extends": "../tsconfig.json",
  "include": ["./", "../src"],
  "exclude": []
}
```

`__test__/tsconfig.json`を追加し、includeとexcludeフィールドを上書きします。これでIDE上での警告が消えます。

`__test__/tsconfig.json`は`__test__`ディレクトリ内でtscコマンドを実行するか、`--project`オプションを指定しない限りトランスパイルには利用されません。プロジェクトに影響を与えず警告だけを消せます。

以上、ありがとうございました。
c2kのgpio mux

comcerto 2000のgpioは64本でc1kの倍になっています。

他の機能との切り替えのレジスタも増えています。

```
#define GPIO_PIN_SELECT_REG	0x58
#define GPIO_PIN_SELECT_REG1	0x5c
#define GPIO_MISC_PIN_SELECT	0x60
#define GPIO_63_32_PIN_SELECT	0xdc
```

c1kはGPIO_PIN_SELECT_REGだけで1ビット単位でそのビットのGPIOの切り替えができました。

c2kでは0-15までが2ビット単位でGPIO_PIN_SELECT_REGで15-31が2ビット単位でGPIO_PIN_SELECT_REG1で32-59が1ビット単位でGPIO_63_32_PIN_SELECTで60-63がGPIO_MISC_PIN_SELECTになるようです。

GPIO_PIN_SELECT_REGは0がgpioになりますがGPIO_PIN_SELECT_REG1とGPIO_63_32_PIN_SELECTは0が他の機能になります。

本家のソースでは読み解く事ができなくて、フランスの人が書いたpinctl-ls1024a.cというコードを眺めていて理解しました。

c1kとまったく互換無いし、なんとも妙な仕様です。
laravelのwebpushで小石に躓いた話

## 状況

laravel-notification-channels/webpushを使用した際に、firefoxでは正常に動くが、chromeで通知許可のポップアップが出ない。
コンソールには以下のエラーが
```
DOMException: Registration failed - missing applicationServerKey, and manifest empty or missing
```

## 解決策
VAPIDの作成を忘れていた。
ずっと実行したと思いこんでいて、Firefoxで動いてたのもあり。Chromeの設定が悪いと疑っていたので盲点だった。

```
php artisan webpush:vapid
```

configをキャッシュしてる人は以下も忘れずに

```
php artisan config:cache
```
Rancher Desktopでkindが使えない

環境
* Mac(M1), Ventura 13.4.1 
* Rancher Desktop 1.9.1
* kind 0.20.0

```sh
$ kind create cluster
Creating cluster "kind" ...
 ✓ Ensuring node image (kindest/node:v1.27.3) 🖼
 ✗ Preparing nodes 📦
Deleted nodes: ["kind-control-plane"]
ERROR: failed to create cluster: command "docker run --name kind-control-plane --hostname kind-control-plane --label io.x-k8s.kind.role=control-plane --privileged --security-opt seccomp=unconfined --security-opt apparmor=unconfined --tmpfs /tmp --tmpfs /run --volume /var --volume /lib/modules:/lib/modules:ro -e KIND_EXPERIMENTAL_CONTAINERD_SNAPSHOTTER --detach --tty --label io.x-k8s.kind.cluster=kind --net kind --restart=on-failure:1 --init=false --cgroupns=private --publish=127.0.0.1:65469:6443/TCP -e KUBECONFIG=/etc/kubernetes/admin.conf kindest/node:v1.27.3@sha256:3966ac761ae0136263ffdb6cfd4db23ef8a83cba8a463690e98317add2c9ba72" failed with error: exit status 125
Command Output: cc8fae461f31c29c4093dd28c9a96dc9b1689121e8cb0b89ec7f5259d31c72e5
docker: Error response from daemon: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: error during container init: error mounting "cgroup" to rootfs at "/sys/fs/cgroup": mount cgroup:/sys/fs/cgroup/openrc (via /proc/self/fd/7), flags: 0xe, data: openrc: invalid argument: unknown.
```

バグっぽい

https://github.com/kubernetes-sigs/kind/issues/3277

kindをダウングレード
```sh
$ cd /opt/homebrew/Library/Taps/homebrew/homebrew-core/Formula
 
$ git log --oneline -n 5 kind.rb
723db0bbeb5 kind: update 0.20.0 bottle.
d17073d2919 kind 0.20.0
2bbd54652f0 kind: update 0.19.0 bottle.
88ad6c6fe6b kind 0.19.0
3dc55237178 kind: update 0.18.0 bottle.
 
$ git ch 2bbd54652f0 kind.rb
$ brew uninstall kind
$ brew install kind.rb
 
$ kind version
kind v0.19.0 go1.20.4 darwin/arm64
```

解決
```sh
$ kind create cluster
Creating cluster "kind" ...
 ✓ Ensuring node image (kindest/node:v1.27.1) 🖼
 ✓ Preparing nodes 📦
 ✓ Writing configuration 📜
 ✓ Starting control-plane 🕹️
 ✓ Installing CNI 🔌
 ✓ Installing StorageClass 💾
Set kubectl context to "kind-kind"
You can now use your cluster with:
 
kubectl cluster-info --context kind-kind
 
Have a nice day! 👋
```
Javaで「ファイルの状態を調べる(実行可能/隠しファイル/読み取り/書き込み/シンボリック・リンク)」の動作を確認してみた

# 概要
Javaで「ファイルの状態を調べる(実行可能/隠しファイル/読み取り/書き込み/シンボリック・リンク)」の動作を確認してみました。以下のページを参考にしました。

https://www.javadrive.jp/start/file/index7.html

# 実装
以下のファイルを作成しました。
```JSample7_1.java
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.Files;
import java.io.*;

class JSample7_1{
    public static void main(String[] args){
	Path p1 = Paths.get("doc/memo1.txt");
	Path p2 = Paths.get("doc/.memo2.txt");
	Path p3 = Paths.get("doc/memo3.txt");

	checkFile(p1);
	checkFile(p2);
	checkFile(p3);
    }
    
    private static void checkFile(Path p){
	System.out.println("ファイル名:" + p.getFileName());
	try{
	    if (Files.isExecutable(p)){
		System.out.println("実行可能：○");
	    }else{
		System.out.println("実行可能：✕");	
	    }
	    if (Files.isHidden(p)){
		System.out.println("隠しファイル：○");
	    }else{
		System.out.println("隠しファイル：✕");	
	    }
	    if (Files.isReadable(p)){
		System.out.println("読み取り：○");
	    }else{
		System.out.println("読み取り：✕");	
	    }
	    if (Files.isWritable(p)){
		System.out.println("書き込み：○");
	    }else{
		System.out.println("書き込み：✕");	
	    }
	    if (Files.isSymbolicLink(p)){
		System.out.println("シンボリック・リンク：○");
	    }else{
		System.out.println("シンボリック・リンク：✕");	
	    }
	}catch(IOException e){
	    System.out.println(e);
	}
    }
}
```
以下のコマンドを実行しました。
```
$ javac JSample7_1.java 
$ java JSample7_1 
ファイル名:memo1.txt
実行可能：○
隠しファイル：✕
読み取り：○
書き込み：○
シンボリック・リンク：✕
ファイル名:.memo2.txt
実行可能：✕
隠しファイル：○
読み取り：✕
書き込み：✕
シンボリック・リンク：✕
ファイル名:memo3.txt
実行可能：○
隠しファイル：✕
読み取り：○
書き込み：○
シンボリック・リンク：○
```

# まとめ
何かの役に立てばと。
【flutter】Widgetを縦並びにするには？

こんにちは。
今回は、Widgetを縦並びにする方法を紹介します。

# 方法
![スクリーンショット 2023-08-13 20.18.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524120/ce57fee2-1687-ea40-8538-b4c8b9db94e0.png)

縦並びにするには、「Column」のウィジェットを使います。



# 使用例
```dart
Column(
          children: [
            Text("文字た"),
            Text("文字て"),
            Text("文字な"),
            Text("文字ら"),
            Text("文字び"),
          ],
        )
      )
```

# 実行例
![スクリーンショット 2023-08-15 14.47.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524120/89f361d5-75c4-0071-7824-3ad7e2f44d64.png)
子供の相手をしてくれるじゃんけん装置（LINE Bot)を作りたい

<blockquote class="twitter-tweet"><p lang="zxx" dir="ltr"><a href="https://t.co/vyZZgKXNgS">pic.twitter.com/vyZZgKXNgS</a></p>&mdash; wamae (@mWNYwPxi8h58533) <a href="https://twitter.com/mWNYwPxi8h58533/status/1691312389801807872?ref_src=twsrc%5Etfw">August 15, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# ■**みんな**それなりに頑張って生きている
　我が家には５歳の息子と３歳と娘がいるのですが、子供の相手って・・・本当に大変。
　世の中のパパさんママさんいつも本当にお疲れ様です。

# ■なぜこれを作ろうと思ったか　
「身の回りの課題解決」がポイント
そう聞いたときに１番始めに思いついたのは子供のことでした。
　家事や自分の作業を進めるには子供には何かに夢中になっていてもらう必要があるのですが、
毎回毎回スマホやテレビでYouTubeばかり見せているのもな～。
勝手に訳のわからない動画や教育によろしくない動画見ていても困るし。
せっかくなら自分が作ったbotで遊んでもらえたら、デジタルツールを媒介に子供の相手できるし、やってみたい！と思ったことでした。

朝は大体Eテレ見ていて、長男のお気に入りはピタゴラスイッチ。
特に番組最後のピタゴラじゃんけん装置はマスト。
なら、LINEbotで自分の代わりにじゃんけんしてくれるやつ作ったろ！

# ■使用したもの
Make 
⇒　https://www.make.com/en
LINE Developers
→リッチメニュー
⇒　https://developers.line.biz/ja/
SSSAPI
⇒　https://sssapi.app/
Google スプレッドシート
⇒　https://docs.google.com/spreadsheets/u/0/
# ■じゃんけんbot実装イメージ
イメージ
じゃんけんなので「グー」「チョキ」「パー」の3種類の3つに反応してリプライが来る。
↓
Botもいずれか「グー」「チョキ」「パー」をランダムで返信。
内容次第で返事が変わる。
↓
利用者が勝った場合、
「あなたの勝ち」

あいこの場合
「引き分け」

利用者負けた場合
「あなたの負け」

**・リッチメニュー**
わざわざ「グー」「チョキ」「パー」を入力するのは大変なので
小さい子供でも遊べるようにタップすれば送信できるようにしてみる。


# ■実際にやってみた
Google スプレッドシートで作成。
グー＝1　チョキ＝2　パー＝3
1の位が自分の出し手
10の位が相手APIの出し手
9通りにid割振りました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3485526/a318600c-b5c1-56e9-812a-5474c8e040b0.png)

SSSAPIでじゃんけん用スプレッドシートを作成
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3485526/1ce6b7a7-4f42-99e3-7431-797b0e4bc813.png)

出てきました！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3485526/da62d787-b49a-df38-f91a-663e5e6f39bd.png)

グーチョキパー3通りをランダムで生成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3485526/c42a80dc-74f1-8a8f-e657-b15b20278e79.png)

:::note warn
※実装前うまくいかないと思ったら半角の3で入力すべきところを全角の３で入力していました。
:::
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3485526/9cb15f99-48ff-e767-c5e3-73145a2aa673.png)


紆余曲折しながらも・・・完成！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3485526/81f6098e-c119-440c-3b63-b64a6419b43b.png)

・リッチメニュー
３つ枠用意してイラストはめ込みました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3485526/7a65fbaf-22a7-09a1-f3c3-551dd9bc1de9.png)

ちゃんと返ってきています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3485526/5dc08db3-56bd-063a-1876-361cee2e889b.png)

アイコンタップでじゃんけんできるようになりました！
難しいしなかなか大変だったけど動くようになるとやっぱり嬉しい。

<blockquote class="twitter-tweet"><p lang="zxx" dir="ltr"><a href="https://t.co/vyZZgKXNgS">pic.twitter.com/vyZZgKXNgS</a></p>&mdash; wamae (@mWNYwPxi8h58533) <a href="https://twitter.com/mWNYwPxi8h58533/status/1691312389801807872?ref_src=twsrc%5Etfw">August 15, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


# ■反省・改善に向けて
現状勝ち負け、引き分けの結果しか話してくれないので無機質な感じ。
出した手に対して「おめでとう！」「また挑戦してね」のようにコメントも併せて返信するようにブラッシュアップしたい。
また、グーチョキパー以外の言葉を送った際のエラーメッセージもRouterで分岐させて返答できるようにする。
Google でログイン (Javascript API)

こちらと同じことを、Javascript API で実装しました。
[Google でログイン　を設定](https://qiita.com/ekzemplaro/items/26abeaba07f57d5f3b0e)

こちらのページを参考にしました。
[【Google】ワンタップログイン](https://uga-box.hatenablog.com/entry/2022/09/21/000000)

## Web ページ

```html:index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>
Login Test
</title>
</head>
<body>
<script src="https://accounts.google.com/gsi/client" async defer></script>
<script src="login.js"></script>
<div id="buttonDiv"></div>
<hr />
<div id="outarea_aa">outarea_aa</div>
<div id="outarea_bb">outarea_bb</div>
<div id="outarea_cc">outarea_cc</div>
<div id="outarea_dd">outarea_dd</div>
<div id="outarea_ee">outarea_ee</div>
<div id="outarea_ff">outarea_ff</div>
<div id="outarea_gg">outarea_gg</div>
<div id="outarea_hh">outarea_hh</div>
<p>Aug/15/2023 PM 13:59</p>
</body>
</html>
```

```js:login.js
// -----------------------------------------------------------------------
function handleCredentialResponse(response) {
	  console.log("Encoded JWT ID token: " + response.credential);
	}

// -----------------------------------------------------------------------
window.onload = function ()
{
	document.querySelector("#outarea_aa").innerHTML
		= "*** login.js *** start ***"

	google.accounts.id.initialize({
	client_id: "371868132900-eg26ng307au*******.apps.googleusercontent.com",
	    callback: handleCredentialResponse
	  });
	  google.accounts.id.renderButton(
	    document.getElementById("buttonDiv"),
	    { theme: "outline", size: "large" }  // customization attributes
	  );
	  google.accounts.id.prompt(); // also display the One Tap dialog


	document.querySelector("#outarea_hh").innerHTML
		= "*** login.js PM 14:16 *** end ***"

}
// -----------------------------------------------------------------------
```

## ブラウザーでアクセス

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/df98640a-541c-8f84-753f-8ade48996ff9.png)

## 関連ページ
[Sign In With Google JavaScript API](https://developers.google.com/identity/gsi/web/reference/js-reference?hl=ja)
ローカル環境でproductionモードでRailsアプリを起動する

# 前提
developmentモードでは問題ないが、productionモードでエラーとなる現象を確認するために行います。

# 手順
1.SECRET_KEY_BASEの値を取得
```
bin/rails secret
```

2.SECRET_KEY_BASEをエクスポート
```
export SECRET_KEY_BASE=(bin/rails secret実行後の値)
```

3.`config/initializers/carriewave.rb`の値をコメントアウト
以下のエラーが出たため
```
 Missing required arguments: aws_access_key_id, aws_secret_access_key (ArgumentError)
raise ArgumentError, "Missing required arguments: #{missing.join(", ")}"
```

4.Railsコンソールをproductionモードで起動
```
RAILS_ENV=production bundle exec rails c
```

5.productionモードであることを確認

```
Rails.env
```

6.データベースを作成
【SwiftUI】AsyncImageビュー

# この記事は何？

SwiftUIフレームワークのAsyncImageビューについて、[開発者向けドキュメント](doc://com.apple.documentation/documentation/swiftui/asyncimage?language=swift)の内容を解説。

> Swiftを基礎から学ぶには
自著、工学社より発売中の「[まるごと分かるSwiftプログラミング](https://amzn.asia/d/7YPWJwl)」をお勧めします。変数、関数、フロー制御構文、データ構造はもちろん、構造体からクロージャ、エクステンション、プロトコル、クロージャまでを基礎からわかりやすく解説しています。

# AsyncImageビュー

AsyncImageビューは非同期的に画像を読み込んで、画面に表示する。

```swift:宣言
struct AsyncImage<Content> where Content : View
```

# 基本的な使い方

このビューは、共有`URLSession`インスタンスを使用して、指定されたURLから画像をロードし、表示する。

次の例は、サーバーにあるアイコン画像を読み込んで、表示するSwiftUIコード。

```swift:
AsyncImage(url: URL(string: "https://example.com/icon.png"))
    .frame(width: 200, height: 200)
```

画像が読み込まれるまで、ビューには使用可能なスペースを埋める標準プレースホルダが表示される。
読み込みが正常に完了すると、ビューが更新されて画像が表示される。
上記の例では、アイコンはフレームよりも小さいため、プレースホルダよりも小さく見える。

`init(url:scale:content:placeholder:)`イニシャライザを使用すると、独自のプレースホルダを指定できる。
このイニシャライザでは、`Content`パラメータを使用してロードされた画像を操作することもできる。
例えば、`resizable`モディファイアを追加すれば、読み込んだ画像のサイズを変更できるようになる。

```swift:
AsyncImage(url: URL(string: "https://example.com/icon.png")) { image in
    image.resizable()
} placeholder: {
    ProgressView()
}
.frame(width: 50, height: 50)
```

この例では、SwiftUIは最初に`ProgressView`を表示する。
そして、縦`50`と横`50`のフレームに指定された画像を表示する。

# 要点

`resizable(capInsets:resizingMode:)`モディファイアのような画像固有のモディファイアは、`AsyncImage`ビューに適用できない。
その代わり、ビューの外観を定義するときに、クロージャが取得した`Image`インスタンスに適用する。

`init(url:scale:transaction:content:)`イニシャライザを使用すると、読み込みプロセスをより詳細に制御できる。
この`content`クロージャには、読み込み状態を示す`AsyncImagePhase`パラメータがある。
そして、現在のフェーズに適したビューを返す。

```swift:
AsyncImage(url: URL(string: "https://example.com/icon.png")) { phase in
    if let image = phase.image {
        image // 読み込んだ画像
    } else if phase.error != nil {
        Color.red // エラーを示す
    } else {
        Color.blue // プレースホルダの役割
    }
}
```
NRQLを見やすくするための「改行」「コメント」活用術

## 概要
日頃New Relicにたくさんのデータを取り込み可視化・分析しているかと思いますが、活用にあたって必須となるのがNRQLです。グラフ化したり条件に合わせて必要データを抽出したりするためにNRQLと日々格闘している方々に朗報です！！
活用するにあたって知っておくとちょっと便利な「コメント」機能が追加されました！
実は「改行」もできるようになっているので、合わせて使い方と活用例をご紹介したいと思います。

:::note info
このアップデートの詳細はこちら。
[New Relic アップデート(2023年４月)](https://newrelic.com/jp/blog/nerdlog/new-relic-update-202304)
[New Relic アップデート](https://newrelic.com/jp/blog/nerdlog/new-relic-update "New Relic アップデート")
:::


## 情報共有するために「コメント」追加
どうゆう意図で作ったNRQLなのかわからなくならないようにコメント入れたいですよね。
コメントの入れ方には下記3パターンあります.

(1)<B>" -- "</B>
2つのダッシュは、同じ行にあるこのインジケーターの右側にあるすべてのテキストをコメントアウトします。
![comment_twodash.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/313446/7bb23ad6-c4fe-0814-4e0c-43fa0b95ea6a.png)

(2)<B>" // "</B>
2つのスラッシュは、同じ行にあるこのインジケーターの右側にあるすべてのテキストをコメントアウトします。
![comment_twoslashes.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/313446/5fc4511f-c834-fd59-b29e-4e8551368f86.png)

(3)<B>" /* */ "</B>
これらの文字セットの間にあるテキストはすべてコメントアウトされます。複数の行に適用したい場合に利用します。
![comment_anytext.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/313446/fa55b848-8b98-cd9c-61e1-a77459ad56d3.png)


これでチームメンバーや新しくプロジェクトに参画した人などが、NRQLを全て解析しなくてもコメントで把握することができるので把握するための学習コストを激減することが可能です。


## 長いNRQLを見やすくするための「改行」
使い方は至ってシンプルです。
ついつい条件をつけすぎて長くなってしまったNRQLありますよね？
途中で<B>「Shift+Enter」</B>を押すだけで改行ができます！
コメントと組み合わせてこんな感じでも使えます！一気に見やすくなりました！
![comment_return.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/313446/6a47df88-4fdf-835d-f1f4-f45f6c330eb8.png)

コメントや改行をフル活用して、New Relicに貯めたデータの有効活用や日々の運用にお役立てください！

:::note info
このアップデートの詳細はこちら。[New Relic アップデート(2023年４月)](https://newrelic.com/jp/blog/nerdlog/new-relic-update-202304)
:::
:::note info
無料のアカウントで試してみよう！
[New Relic フリープランで始めるオブザーバビリティ！](https://qiita.com/ktst79/items/5ee74b34e6adb8a7a6fa)
:::
:::note info
[New Relic株式会社のQiita OrganizationOrganization](https://qiita.com/organizations/newrelic)では、
新機能を含む活用方法を公開していますので、ぜひフォローをお願いします。
:::