OmniAICreator/Qiita-1.07M huggingface dataset:
AWS Summit 2024


開催日時: 6/20 10:00 ~ 6/21 17:00
場所: 幕張メッセ

https://aws.amazon.com/jp/summits/japan/

![IMG_8811.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483556/9f5085a8-ac12-61a8-6084-267688cbfe92.jpeg)

AWS Summit 2024に行ってきました。

今年で13回目らしい。例年参加者が増えていて、去年より多かった印象。
始めのセッションや企業ブースが10時から開始なのに対して、朝9時くらいから行列が出来てた。8時40分ごろに付いた時点ではそこまで列ができてなかったし、基調講演の整理券(今年は指定席)とお弁当の引換券は普通に手に入った。お弁当は結構あまるので、引換券なくても昼頃に引換場所へ行けば余裕で手に入る。今年はまいせんのかつサンド弁当と唐揚げ弁当。

## クッション
去年よりかはいいかな？
持ち運びやすいようにゴムで縛れるようになってる。
基調講演微妙に長いから、背中に置くと良かった。

![IMG_8862.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483556/627b1b9e-9d9a-a633-d8c7-6d19507b1b53.jpeg)

## サーバレスコーヒー
ネーミングがなんかいいよね！
無料のコーヒーを配ってるんだけど、そこにもAWSを使ってなんかいいね！
モニターのQRコードをスマホで読み込んで、サイトに欲しいコーヒーを選択して注文すると、オーダー番号が表示されて呼ばれたら店員さんに見せて引換する仕組み。

![IMG_8827.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483556/201db943-b840-0d22-f53b-36bcc2cff0a6.jpeg)
おいしかった。

## 認定ラウンジ
シール欲しさに1日目の10:40頃には並んだ。おかげで持っている資格のシールは全て手に入った。どうも一日目の終わりには、DVAとSAPがなくなってたらしい。SAPは数が少ないんかな？

DEAはシールとクッキーがもらえるんだけど、胸ポケットに入れてたら、砕けてた、
基調講演でもらったクッションに包んでれば良かった。

## 記念撮影
スポットはいくつかあるけど、メインはここ。

![IMG_8855.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483556/d8107243-d7d5-94a6-469c-0147ccc99759.jpeg)

## まとめ
正直、お祭り感はあんまりなかったかな、
いつもの幕張で行われるイベントって感じ。
もうちょっと、企業の営業感をなくして、純粋にAWSを楽しむイベントもありかなと思った。まぁ。しゃーないけど。
WiresharkのpcapファイルからIP間の通信頻度を可視化する

# はじめに

Wiresharkのパケットキャプチャの結果 (pcapファイル) からIPアドレスの繋がりを可視化しました．

本当はネットワークのグラフのようなものを作りたかったのですが，Wiresharkでは第三者同士の通信は見られないことにコードを書いている最中に気づきました……

# 読み込み

雑に実装．コマンドライン引数でファイル名を指定

``` py
import pyshark
import networkx as nx
import matplotlib.pyplot as plt
import sys

args = sys.argv
pcap_file = args[1]
cap = pyshark.FileCapture(pcap_file)
cap.set_debug()
```

# グラフの作成

おなじみNetworkX．

pcapファイルはfor文でパケットごとに分割でき，送信元と送信先のIPアドレスを取れます．

通信回数をカウントしてそれを重みにします．
重みを指定すると辺の太さだけでなくノードの位置も調整してくれるんですね，すごく便利．

``` py
G = nx.Graph()
edge_count = {}

for packet in cap:
    if 'IP' in packet:
        src_ip = packet.ip.src
        dst_ip = packet.ip.dst
        if (src_ip, dst_ip) in edge_count:
            edge_count[(src_ip, dst_ip)] += 1
        elif (dst_ip, src_ip) in edge_count:
            edge_count[(dst_ip, src_ip)] += 1
        else:
            edge_count[(src_ip, dst_ip)] = 1

for (src_ip, dst_ip), count in edge_count.items():
    G.add_edge(src_ip, dst_ip, weight=count)
```

# グラフの描画

``` py
plt.figure(figsize=(12, 8))
pos = nx.spring_layout(G)  # ノードの位置を決定
nx.draw(G, pos, with_labels=True, node_size=50, font_size=8, font_color='black')
plt.title('Network IP Graph from pcap file')
plt.show()
```

# 結果

適当に手元の通信を直で取りましたが，良い感じに通信量が可視化できていると思います．
やはりプライベートの通信が一番多いですね．

(IPアドレスは塗りつぶしていますが，真ん中の2ノードのようにちゃんと表示されます)

![イラスト.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609800/da792f49-73ce-a793-f54f-21a90c61cecf.png)
AWS節約術 : S3標準 vs Glacierの損益分岐点は何KBか？

S3に置きっぱにされやすいログとかのデータは、ついGlacierに移行したくなりますよね？

でもGlacierには最低保持期間だったりの縛りの他、
いくつかの追加料金も発生します（移行イベント、ヘッダ、最低保持サイズ）

じゃあ一体いくらからGlacierに移行するのがお得なのか・・・？

具体的には、

> S3にオブジェクトファイルをばーっといっぱい上げて、サイズ条件で適切なストレージクラスに変更したいが、一体いくつに設定すればよいのか

という疑問が有りまして、
これに答えられるよう計算してみました。

---

# 結論

* 東京リージョンで
* S3のオブジェクトをライフサイクルで移行して
* ６ヶ月保存した

の条件下で比較すると、損益分岐点は次のようになりました。

* 標準 VS Glacier Instant Retrieval (新 Glacier) ... 約40KBで損益分岐点を迎える
* 標準 VS Glacier Flexible Retrieval (旧 Glacier) ... 約300KBで損益分岐点を迎える
* 標準 VS Glacier Deep Archive ... 約480KBで損益分岐点を迎える

ひとつずつ見ていきます

---

# 発生するコスト

1. まずはストレージ料金が発生します。ファイルサイズ（オブジェクトサイズ）によって課金されます
2. 次にライフサイクルの移行リクエストに課金されます
3. 最小オブジェクトサイズを考慮します。これより小さいオブジェクトサイズはこの最小オブジェクトサイズとして課金計算されます
4. 最後にメタデータ追加分の課金が有ります。旧GlacierとDeepArchiveは、オブジェクトサイズとは別に40KB分の課金が発生します。

特に、3と4については下記のように記載が有ります。

https://aws.amazon.com/jp/s3/pricing/?nc1=h_ls


> S3 Glacier Instant Retrieval の課金対象となる最小オブジェクトサイズは 128 KB です。128 KB より小さいサイズのオブジェクトを保存することもできますが、適切なストレージクラス料金で 128 KB のストレージとして課金されます。

> S3 Glacier Flexible Retrieval または S3 Glacier Deep Archive に保存されている各オブジェクトの場合、Amazon S3 はメタデータに対する課金可能な 40 KB のオーバーヘッドを追加し、それは、S3 標準レートで請求される 8 KB と S3 Glacier Flexible Retrieval または S3 Deep Archive レートで請求される 32 KB から構成されます。

この辺が単純に何でもGlacierにしても逆に高くついてしまう理由ですね。

---

# 式にしてみた

式で書くと、次の用になります。

（東京リージョン）

### S3標準

    S3標準 = オブジェクトサイズ * 0.025[USD/GB/月]

### Glacier Instant Retrieval (新 Glacier)

    新Glacier = max(オブジェクトサイズ, 128KB) * 0.005[USD/GB/月] + 0.000002[USD](ライフサイクルリクエスト)

ここまではわかりやすいです。

### Glacier Flexible Retrieval (旧 Glacier) 

32KB分のサイズ追加と、8KBのS3標準分の追加があります。


    新Glacier = (オブジェクトサイズ + 32KB) * 0.0045[USD/GB/月] + 0.000003426 [USD](ライフサイクルリクエスト) + 8KB * 0.025[USD/GB/月]

### Glacier Deep Archive

ライフサイクルのリクエストコストが高めです。

    DeepArchive = (オブジェクトサイズ + 32KB) * 0.002[USD/GB/月] + 0.0000065 [USD](ライフサイクルリクエスト) + 8KB * 0.025[USD/GB/月]


この設定でグラフを書いたところ、下記のようになりました。
※ ライフサイクルコストはストレージ最低保持期間の180日=6ヶ月で割って、1月当たりのコストに換算して計算しました。

![Screenshot 2024-06-21 at 22-55-42 S3ストレージクラス損益分岐点.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3812996/c010fdc2-7cb9-d3e9-fb0c-46f1ad14b18c.png)

メタデータとライフサイクルリスクエストのコストが効いて、
なかなか小さいサイズをGlacierにできなかったのですが、
新Glacierが、そのへんの空いているレンジをカバーしていますね。えらい。

---

そんなわけで、東京リージョンにおいては、40KBまでは標準で良くて、
そこからは先はGlacierにしてコストを浮かせる検討をしてみるのが良さそうです。

もちろんGlacierにはいろんな制限があるので、S3標準クラスでもありだし、標準〜Glacierの中間にいるクラスへの移行も検討範囲です。

それでは皆様、よいAWS節約ライフを！（何
QNAPとUbuntu Linux Station

### QNAP側でNFSを有効に
```
[ControlPanel]
- [ネットワークとファイルサービス]
- [Win/Mac/NFS/WebDAV]
- [NFSサービス]
チェックON=[ネットワークファイルシステム(NFS)サービスを有効にする]
チェックON=[NFSv2とNFSv3]
```
### QNAP側でSSHServerを有効に
```
[ControlPanel]
- [ネットワークとファイルサービス]
- [Telnet/SSH]
チェックON=[SSH接続を許可する(管理者だけがリモートログインできます。)]
ポート番号[22]
チェックOFF=[SFTPを有効にする]
[アクセス許可の編集]=adminとsshする管理者ユーザ名を登録
```
### Ubuntu側にSSHServerをインストール
```
sudo apt -y install openssh-server
```
ステータスを確認
```
sudo systemctl status ssh
```
### UbuntuからQNAPのPublicフォルダをマウント
NFSクライアントを準備
```
$ sudo apt -y install nfs-common
$ mkdir -p /nfs/Public
$ vi /etc/fstab
# UNCONFIGURED FSTAB FOR BASE SYSTEM
TS-464-1:/Public /nfs/Public nfs defaults 0 0
$ sudo mount /nfs/Public
```
JDLA Generative AI Test 2024 #1に合格したので色々まとめてみた

# 事の起こり
JDLA(日本ディープラーニング協会)が2023年6月から実施しているGenerative AI Testの2024年第1回を受験して無事:cherry_blossom:合格:cherry_blossom:したので、受験後すぐに投稿した記事では触れなかった内容についてまとめておこうと思います。

https://www.jdla.org/news/20240621001/

受験後すぐに以下の記事を投稿しました。試験の問題形式等は以下の記事で触れているので割愛します。

https://qiita.com/y-vectorfield/items/7af3c625528bfe6d1a77

# 受験の動機
前回の記事では受験の動機について、全く触れていませんでした。実はこの試験を受験するのは、今回で3回目です。1回目の受験はこの試験の初回実施の時で、この時は全ての問題が択一式、複数選択式で記述問題が有りませんでした。この回は無事合格し、オープンバッチもゲットしました。しかし、2回目から記述問題1問を含む20問に問題形式が変更になりました。形式変更後の試験でも合格したいと思い、昨年の12月に2回目を受験したのですが、ちょうど試験当日別件と予定がブッキングしてしまい、実際に試験を受験出来たのは、終了時間ギリギリ。。。:sob: 見直しも禄に出来ないままタイムアップ。。。案の上不合格になってしまいました。:sob: 業務でAIに関わっているため、不合格のままでは寝覚めが悪いということで、3回目の受験を思い立ちました。

# 試験結果
どれぐらいの得点率で合格となるのか、基準が公表されていないので分かりません。これぐらいの得点率は欲しいという基準が有る絶対方式なのか、平均点なども加味した相対方式なのか、回によって異なるのかもよく分かりません。。。IBT形式の試験ではこの傾向が強い様な気がします。

1.生成AIの技術　正答率：71 ％
2.生成AIの利活用　正答率：100 ％
3.生成AIのリスク　正答率：88 ％

参考までに初回(2023 #1)での得点率です。こうして見ると、筆者は生成AIの技術分野の得点が前回と変わっていません。。。利活用とリスクについては点数が上がっています。しかし、20問中それぞれの問題が何問といった出題数等に関する情報は公開されていないため、実際の点数はよく分かりません。ただ、初回受験時は利活用の分野が得点率60％を切っていますが、合格しました。ひょっとすると平均で6割や、総合6割という可能性も、無きにしも有らずですね。。。

1.生成AIの技術　正答率：71 ％
2.生成AIの利活用　正答率：57 ％
3.生成AIのリスク　正答率：83 ％

## 詳細を予想
あくまで、今回の試験においての予想にはなりますが、各問の出題数は以下の様になっていたのではと推察されます。

|分野|問題数|筆者の正答数|
|:---:|:---:|:---:|
|生成AIの技術|7|5|
|生成AIの利活用|4|4|
|生成AIのリスク|9|8|
|合計|20|17|

解説を見つつ出題された問題を思い返していたのですが、複合的な問題と言えなくもない問題の出題も有ったため、この分野が○問という形式になっていない可能性も有ります。

# 試験で取り上げられていた時事問題
以下の報道記事でも取り上げられている、米国や中国のAIに対する規制、EUの規制など毎回時事問題が出題されます。よってAI関連の法整備に関する報道など、学術的、技術的な側面以外のAIに関する報道も定期的にウォッチする重要性に気付かされました。

https://www.jetro.go.jp/biznews/2023/11/495833ae70119dbf.html

https://www.yomiuri.co.jp/economy/20230815-OYT1T50417/

# まとめ
Generative AI Testに合格したことを受けてまとめ記事を投稿しました。今後、試験の復習とAIに対するより深い理解のため、以下のキーワードについて、より詳しく勉強したいと思います。

* RAG
* ハルシネーション
* プロンプトエンジニアリング
* プロンプトインジェクション
* AIの心理学
Edge で Copilot を使用してコンソールのエラーと警告を説明する

# 背景

いつものように F12 を押して Edge DevTools を開いたところ、What's New が気になることがあった

:thinking:

で、目を通してみたところ、めっちゃ便利な機能が Release されていました。

https://learn.microsoft.com/ja-jp/microsoft-edge/devtools-guide-chromium/console/copilot-explain-console

動画で見たほうが分かりやすいはず

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

# 概要

- Copilot に、簡単に聞ける

## 今まで

エラーメッセージをコピペしたり、状況を説明して質問

## 今後

Copilot アイコンを押すだけ

サイドバーに Copilot が表れて回答してくれる。

何がいいって、

- 簡単
- minify も理解して回答してくれる

# 動作を試してみたい人は

以下ページで、Run を押して、Console から Copilot Icon を押せば OK

https://microsoftedge.github.io/Demos/devtools-explain-error/

実際の画面

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/dffe749d-e99a-1038-63a2-a993f216e84c.png)

# あとがき

VS Code なんかもどんどん便利になっていってるから、ついていくことすら出来ない :sweat:
C# 自分用メモ その3 演算子のオーバーロード

# 1. はじめに
私はいい歳したC/C++屋さんなのですが、必要に迫られてC#を触っています。そんなこんなで「ん～これはハマりそうだな」と思った事を記録しておきます。自分用メモ。

代入演算子がオーバーロードできないのは痛いなぁ。

# 2.参照先
[https://learn.microsoft.com/ja-jp/dotnet/csharp/language-reference/operators/operator-overloading]()

https://learn.microsoft.com/ja-jp/dotnet/csharp/language-reference/operators/operator-overloading
Salesoforceレポート絞り込み条件で相対日付を使用し「〇日以内」のレコード抽出方法

本橋孝昭です

Salesoforceレポート絞り込み条件で相対日付を使用し「〇日以内」のレコード抽出方法　をお伝えします


今回は例として
・今日は2024年6月21日
・今日から7日以降の日付のレコードを抽出したい（6月21日から6月28日まで）

とします


その場合、相対日付で絞り込みましょう

レポートの結果はこのようになります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/ddb8523c-bd70-86d1-e8ef-d7a98d24a8ad.png)


相対日付で絞り込みます

この相対日付を使えば
・今日（6月21日時点）では6月21日から6月28日まで
・明日（6月22日時点）では6月22日から6月29日まで
・明後日（6月23日時点）では6月23日から6月30日まで

とその時点での日付により動的に絞り込み条件が変わるので便利です
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/d2639cdf-9dae-2f97-abdb-51a21b289cd3.png)


なお、そのほかのSalesforceで使える相対日付はこちらをご確認ください

https://help.salesforce.com/s/articleView?id=000382859&language=ja&type=1

https://help.salesforce.com/s/articleView?id=sf.filter_dates_relative.htm&type=5
Gitコマンドチートシート自分用

## 基本操作
- `git init`: 新しいGitリポジトリを作成する
- `git clone <repository>`: 既存のリポジトリをクローンする
- `git add <file>`: ファイルをステージに追加する
- `git commit -m "message"`: 変更をコミットする
- `git status`: ワーキングディレクトリの状態を表示する
- `git log`: コミット履歴を表示する
- `git diff`: 変更内容を表示する
- `git rm <file>`: ファイルを削除し、削除をステージに追加する

## ブランチ操作
- `git branch`: ブランチを表示する、作成する、削除する
- `git checkout <branch>`: ブランチを切り替える
- `git merge <branch>`: ブランチをマージする
- `git rebase <branch>`: ブランチをリベースする
- `git branch -d <branch>`: ブランチを削除する
- `git switch <branch>`: 新しいブランチに切り替える（`checkout`の代替）

## リモートリポジトリ操作
- `git remote`: リモートリポジトリを表示する、追加する、削除する
- `git fetch`: リモートリポジトリからデータを取得する
- `git fetch` -p: リモートリポジトリからデータを取得し、存在しないリモート追跡ブランチを削除する
- `git pull`: リモートリポジトリからデータを取得してマージする
- `git push`: ローカルのコミットをリモートリポジトリに送信する
- `git remote add <name> <url>`: 新しいリモートリポジトリを追加する

## ステージとコミットの操作
- `git reset`: ステージやコミットをリセットする
- `git revert <commit>`: 特定のコミットを打ち消す新しいコミットを作成する
- `git commit --amend`: 直前のコミットを修正する
- `git reset --hard <commit>`: 指定したコミットにハードリセットする

## 便利なツールとその他のコマンド
- `git stash`: 変更を一時的に保存する
- `git stash apply`: 一時保存した変更を適用する
- `git stash pop`: 一時保存した変更を適用して削除する
- `git cherry-pick <commit>`: 特定のコミットを現在のブランチに適用する
- `git tag`: タグを操作する
- `git archive`: リポジトリ内容をアーカイブする
- `git bisect`: バイナリサーチを使ってバグを探す
- `git blame <file>`: 各行の変更者を表示する
- `git clean`: ワーキングディレクトリをクリーンアップする

## 設定と情報
- `git config`: Gitの設定を操作する
- `git show`: オブジェクト（コミット、ツリーなど）の詳細情報を表示する
- `git describe`: 最も近いタグ情報を表示する

## コラボレーション
- `git submodule`: サブモジュールを管理する
- `git worktree`: 複数のワーキングディレクトリを管理する
【Azure】Bastionを使用してVMにEntraID認証ログインする際の注意事項

BastionのEntraID認証を試してハマったため、備忘録として残します。
基本的な手順は公式URLの紹介に留め、注意点を書き残します。

## EntraID認証ログインの方法
手順については公式を参照ください。

https://learn.microsoft.com/ja-jp/entra/identity/devices/howto-vm-sign-in-azure-ad-windows


## 注意点
1.外部ユーザー(ゲストユーザー)はEntraID認証不可。
>Microsoft Entra Guest アカウントは、Microsoft Entra 認証を介して Azure VM または Azure Bastion 対応 VM に接続できません。


2.ネイティブクライアントを利用したログイン必須(BastionはStandard)
>Azure Bastion を使用して、Azure CLI やネイティブ RDP クライアント mstsc を介して Microsoft Entra 認証でのログインができます。


3.接続方式ごとに接続元マシンの制約が存在する

パスワードレス認証(Windows10,11,Server2022のみ対応)
>Windows クライアント マシンは、Microsoft Entra に登録されているか、VM と同じディレクトリに Microsoft Entra に参加しているか、Microsoft Entra ハイブリッドに参加している必要があります。

パスワード/制限付きパスワードレス認証
>Microsoft Entra 参加済みの VM にリモート接続できるのは、VM として "同じ" ディレクトリに Microsoft Entra 登録済み (最低限必要なビルドは 20H1)、Microsoft Entra 参加済み、または Microsoft Entra ハイブリッド参加済みの Windows 10 以降の PC からのみです。
C# 自分用メモ その2 Dictionary は ソートされない

# 1. はじめに
私はいい歳したC/C++屋さんなのですが、必要に迫られてC#を触っています。そんなこんなで「ん～これはハマりそうだな」と思った事を記録しておきます。自分用メモ。

実行結果は以下のようにソートされていません。C++で言う所の unordered_map みたいだね。

```
[3:2]
[1:2]
[4:1]
[5:3]
[9:1]
[2:1]
[6:1]
```

# 2.というわけでコード
```C#:Program.cs
using System;
using System.Collections.Generic;

namespace DictionaryTest
{
    class Program
    {
        static void Main(string[] args)
        {
            // key, カウンタ
            Dictionary<int, int> dicTest = new Dictionary<int, int>();

            Func(dicTest, 3);
            Func(dicTest, 1);
            Func(dicTest, 4);
            Func(dicTest, 1);
            Func(dicTest, 5);
            Func(dicTest, 9);
            Func(dicTest, 2);
            Func(dicTest, 6);
            Func(dicTest, 5);
            Func(dicTest, 3);
            Func(dicTest, 5);

            foreach (KeyValuePair<int, int> dicItem in dicTest)
            {
                Console.WriteLine("[{0}:{1}]", dicItem.Key, dicItem.Value);
            }
        }

        static void Func(Dictionary<int, int> dic, int n)
        {
            if(!dic.ContainsKey(n))
            {
                dic[n] = 1;
            }
            else
            {
                dic[n]++;
            }
        }
    }
}

```
初めてのsession manager

# EC2インスタンスにキーペアなしで接続する方法（Session Manager編）

## 対象読者
初心者

## 概要
Session Managerを使用すると、キーペアを使わずにEC2インスタンスへSSH接続できます。これにより、キー管理の負担が軽減され、セキュリティが向上します。

## 設定方法

### 手順概要
1. EC2インスタンスをプライベートサブネットに作成し、IAMロールをアタッチ
2. 必要なVPCエンドポイントを作成
3. Session Managerを使用して接続

### 詳細手順

1. EC2インスタンスの設定
   - プライベートサブネットにEC2インスタンスを作成
   - IAMロール「AmazonSSMManagedInstanceCore」をEC2インスタンスにアタッチ
     - このロールにより、インスタンスがAWS Systems Managerと通信できるようになります

2. VPCエンドポイントの作成
   以下のエンドポイントをプライベートサブネットに作成します：
   - com.amazonaws.region.ssm
   - com.amazonaws.region.ec2messages
   - com.amazonaws.region.ssmmessages
   
   注: 'region'は使用しているAWSリージョンに置き換えてください（例：us-east-1）

3. VPCエンドポイントのセキュリティグループ設定
   - 作成したエンドポイントのセキュリティグループを適切に設定
   - 必要なポートと通信を許可（一般的にはHTTPS、ポート443）

4. Session Managerを使用した接続
   - AWSマネジメントコンソールからSystems Managerに移動
   - Session Managerを選択し、対象のEC2インスタンスに接続

## 注意点
- EC2インスタンスにはSSM Agentがインストールされている必要があります（最新のAmazon Linux 2では通常プリインストール済み）
- IAMユーザーまたはロールにSession Manager使用の権限が必要です
C# 自分用メモ その1 クラスは「参照"型"」なのだそうです。

# 1. はじめに
私はいい歳したC/C++屋さんなのですが、必要に迫られてC#を触っています。そんなこんなで「ん～これはハマりそうだな」と思った事を記録しておきます。自分用メモ。


# 2.コードその1
実行結果に"1"が表示されるので参照渡しかなぁと思った私。

```C#:Program.cs
using System;
using System.Collections.Generic;

namespace ListTest
{
    class Program
    {
        static void Main(string[] args)
        {
            List<int> testList = new List<int>();
            MyFunc(testList);

            System.Console.WriteLine(testList[0].ToString());
        }

        static void   MyFunc(List<int> aList)
        {
            aList.Add(1);
            return;
        }
    }
}

```
# 3.指摘を受けました(コードその2)
もし、「参照渡し」なのならばこのプログラムで「2」が表示されるはずなのですが、実際は「1」が表示されます。「参照型の値渡し」なのだそうです(なかなかパラダイムシフトな用語だわ...)

```C#:Program.cs
static void Main(string[] args)
{
    // 値型に見えるが、C#ではクラスは「参照型」である。
    List<int> aList = new ();
    aList.Add(1);
    MyFunc(aList);

    // 上の結果から"2" が表示されることを期待するが、
    //   結果は"1"が表示される。なぜだ ?
    // -> 参照型を値渡ししているからこうなる。
    foreach (int x in aList)
    {
        Console.Write($"{x} ");
    }
    Console.WriteLine();
}

// 参照型が値渡しされる
static void MyFunc(List<int> listA)
{
    List<int> listB = new();

    // listBに対する超複雑な処理のつもり
    listB.Add(2);
    // 途中でlistAのデータを見るかもしれないので
    // listAは最後まで壊さない

    // listAが参照渡しなら結果は2が表示されるはず
    listA = listB;

    //　listAは値渡しされているだけなので破棄される。
    //  listBも(当然)破棄される。
}
```

こういうことか、と。みんなハマってんだなぁ。
https://qiita.com/yutorisan/items/15e1b6bf21d70770de07

# 4.では関数引数の中身を壊したくない(値渡しにしたい)場合はどうするか

```C#:Program.cs
void MyFunc(List<int> ListA)
{
   List<int> ListB = new(ListA);

    // ごにょごにょ
}

```
なのだそうです

# 5. C++ではどうなるのか
コード1を見た目のまま書いてみます。C++であればコピーコンストラクタが働きますから「呼び出し元のaListの中身は変わらない」のです。表記が似てるけれども動きがちがう。C++ と C# は(あたりまえですが)非なるものということでいきなりハマってしまいました。やれやれ。

```C++:list5.cpp
#include <iostream>
#include <list>

void    MyFunc(std::list<int> worklist);

int main()
{
    std::list<int> aList;
    MyFunc(aList);

    // aListの中身は空のままなので何も表示されない
    for (int x : aList) {
        std::cout << x;
    }
    std::cout << std::endl;
}

void    MyFunc(std::list<int> worklist)
{
    // この時点で コピーコンストラクタが働く。
    // worklist と aListとは別物

    worklist.push_back(1);

    // 関数を抜けた時点でworklistは破棄される。
}

```
# 6. 3の状況をC++で無理やり再現してみた(蛇足)
blonz3977 様、補足ありがとうございます。

```C++:list6.cpp
void MyFunc(std::list<int>* pList);

int main()
{
    std::list<int> *aList=new std::list<int>();
    aList->push_back(1);
    MyFunc(aList);

    // 1 のみ表示される
    for (int x : *aList) {
        std::cout << x;
    }
    std::cout << std::endl;
}

void    MyFunc(std::list<int>* pListA)
{
    std::list<int> *listB=new std::list<int>();
	listB->push_back(2);

    // ポインタを上書きしているだけなので呼び元の aList にはなにも作用しない。
	pListA = listB;

    delete listB;
}
```

コメント頂いた皆様に感謝申し上げます。
TypeScriptの`infer`がわからない…でも大丈夫！1つずつ理解する`infer`型

`infer`という型があります。
どうやって使っていいのかいまいち理解できていないので使える（読める）ようになるため理解を深めたいと思います！

:::note
読んだ人が`infer`型を理解して明日からわかることを目指して記事を書きます！
:::

## `infer`型とは？
条件付の型（Conditional Types）の`extends`の中で利用でき、推論される型を抽出できます。

:::note warn
は？って感じですよね…僕も同じ気持ちでした…。
具体例を見ていきます。
:::

## `infer`型はどのようなものか？
コードの例をサバイバルTypeScriptからコードを借りてきました。

```typescript
type Flatten<T> = T extends (infer U)[] ? U : never;
```

上記のコードを分解していきます！

```typescript: inferを利用して配列であるかどうかを確認します
(infer U)[]
```

```typescript: extendsを利用してT型に含まれる型をチェックします
T extends
```

```typescript: 条件がtrueならU型、falseならneverを返します
条件 ? U : never;
```

よってサンプルコードはT型が配列であれば配列の中の型を返し、そうでなければ`never`型を返す`Flatten<T>`が定義されています！

:::note
`extends`を利用した「Conditional Types」の中で利用して型の制限をかけるために利用される型のようです！
:::

## `infer`型の使いどころ
下記の記事に書かれていた表現が一番しっくりきました！

https://reosablo.hatenablog.jp/entry/2020/08/25/005957

- 何かの型を持つ配列
- 何かの型でfulfillされるPromise
- 何かの型のプロパティ"abc"を持つオブジェクト

の何かの型を取得したい場合に必要なのが`infer`型。

## まとめ
`infer`型の理解度はいかがでしょうか？
個人的にはかなりスッキリしました！

:::note
ただ、本当に使う日は来るのか…とは思いますがライブラリなどの型定義を読む際には役立つのではないかと思っています！
:::

- `infer`型は`extends`「Conditional Types」の中で利用する
- ある型の中に含まれる型を抽出するために利用できる

## おまけ
Type-Challengesをやっていて面白い記述に出会いました。
`infer`型を使うとこんなことができるのか…と思ったので共有です！

https://github.com/type-challenges/type-challenges/tree/main/questions/00531-medium-string-to-union

問題と被ってはいけないので少しだけコードを変えてます。

```typescript
type test = 'hoge'

type StringToUnion<T extends string> = T extends `${infer F}${infer R}`
  ? F | R : never;

type Test = StringToUnion<test>
```

上記の結果は`type Test = "h" | "oge"`になります。

```typescript:ここで文字列をユニオン型に変換
<T extends string>
```

```typescript:1文字目がF、それ以降がRに入る
`${infer F}${infer R}`
```

```typescript:最終的に「h」と「oge」が分割されたユニオン型になる
type Test = "h" | "oge"
```

正直全てを理解できてないですが、こんなことができるのか…と覚えておきたいと思いました。

## 参考にした記事
- [TypeScriptのinferを一撃で理解する](https://reosablo.hatenablog.jp/entry/2020/08/25/005957)
- [【TypeScript】inferは怖くない](https://qiita.com/iwata-goq/items/677251ce778afcacd33e)
- [【TypeScript】 inferに詳しくなろう](https://qiita.com/ehika/items/8f41d4a3c8f9df4af9c3)
- [サバイバルTypeScript](https://typescriptbook.jp/reference/type-reuse/infer)
【読書感想文】ジェイソン流お金の稼ぎ方　〜35歳から転職を目指すパパが読んでみて感じたこと〜


## １．はじめに
前回出版された「[ジェイソン流お金の増やし方](https://www.amazon.co.jp/%E3%82%B8%E3%82%A7%E3%82%A4%E3%82%BD%E3%83%B3%E6%B5%81%E3%81%8A%E9%87%91%E3%81%AE%E5%A2%97%E3%82%84%E3%81%97%E6%96%B9-%E5%8E%9A%E5%88%87%E3%82%8A%E3%82%B8%E3%82%A7%E3%82%A4%E3%82%BD%E3%83%B3/dp/4835646460)」と同様とても読みやすかった。また、ジェイソンの本職であるIT関係の話も出てきて、エンジニア転職を目指す私としてはとても有用な情報がたくさんあり、あっという間に読み終わった。全体的にわかりやすく解説してあるが、その中から特に印象に残ったことを取り上げて、私の感じたことを書きたいと思う。



## 1. 世の中に必要なものを察知する
ジェイソンは、トレンドを読み解く重要性を強調している。特に「自分に優れたスキルがあっても、世の中で必要とされていなければ仕事として成立しない」の言葉には**グサッ**とくるものがあった。自分が将来のためと思って勉強しているプログラミングも、**何のために**を意識しないと意味がないということに気づけた。（やみくもに基礎文法や、コンペに取り組んでもダメなんだな〜と私は感じた）
このためには、Podcast等を使って情報収集することが勧めてあったので、私も早速通勤時やランニング中に聞き始めた！（ちなみに、今日聞いたやつでプログラミング言語の「[LISP](https://xtech.nikkei.com/atcl/nxt/column/18/02149/072600001/)」というものを初めて耳にした。）



## 2. 世の中に必要な人材になる。そのための特技の掛け合わせ
ジェイソンは「IT✕日本語」の能力を追求してことで、会社の役員にまでなることができた。たとえば、プログラミングだけだと、母数（ライバル）が多いが、これに英語のスキルをかけ合わせると母数（ライバル）が減る（ただし、英語が普及している国は多いため、唯一性はないとのこと）。
また、これを達成するためにコツコツ努力する重要性も説明している。「なにが重要かを確かめながら動かしていく」ことで成功しやすくなる。いきなり多くの時間をかけてゴールを目指すよりも（MVP[MinimumViableProduct])という考え方「人々の希望を満たす最小限の価値をもたらすプロダクトの提案」を推している。



## ３.成長のスピードを重視する
成長スピードを意識する上でジェイソンは、成長できる職場・職務を選択し、個人の専門性の向上を重要視している。特にコロナ禍で[ジョブ型雇用](https://www.persol-group.co.jp/service/business/article/405/)が注目されており、今後はこれに移行すると予測している。成長を早めるポイントとしては以下が記載されている。
- 最初の５年は稼ぐより成長重視
- 目標をガチガチに決めない
  その目標にこだわり過ぎると、目標に少しでも逸れたものは手をつけなくなる＝他のチャンスを逃していまう可能性がある。そして計画通りにいかなくなると挫折してしまう。そうならないように日々小さな目標を立てて達成するを長期間積み重ねることが重要
- 責任を負う
  「**立場が人を育てる**」いっそことの重責を負うのも成長のコツ。その分頑張って勉強するので成長できる。
- お金を基準に目標を決めない
  お金を基準にしてしまうと、だいたいそこから成長しない。将来なりたい姿になるために必要なスキルをつけて経験を積むことで、それに見合ったポジション・収入がついてくる。
ECHONET Lite対応機器開発に役立つツール3選 

ECHONET LiteはHEMS機器の通信プロトコルです。 
ECHONET Lite対応機器のデバッグ、動作確認で役立つツールをご紹介します。 
今回は入手のし易さを考慮して「フリーで入手・使用できるツール」という縛りで3つ選んで、ご紹介します。 

## その① Wireshark、ECHONET-Lite-dissector 

開発した機器が正しいパケットを出力しているか確認したいケースがあります。 

その場合、ネットワーク上のパケットをキャプチャ、解析ツールが必要となります。 

Wiresharkはそのような用途で使用できる超有名なツールです。超有名なツールであるため、Wireshark本体については、他の解説記事を参照してください。 

ここではWiresharkに追加するECHONET Liteのプラグイン「ECHONET Lite dissector」をご紹介します。 

入手、使用法は次のWebページを参照してください。 

https://github.com/mzyy94/ECHONET-Lite-dissector 

プラグイン導入前後で同じパケットを表示して比較してみます。 
* プラグイン導入前
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817840/a8c034da-be4d-166d-c25b-ae2a56d500f8.png)

* プラグイン導入後
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817840/3add81e2-fa98-d628-ffa0-44174756c367.png)
導入前は16進数の羅列で、パケットの解析も一苦労ですが、導入後はオブジェクトの種類(照明、エアコン等)、サービスコード(GETやSetC等)、データなどが解析済で表示されていて、非常に解析が捗ります。

## その② SSNG for Node.js
ECHONET Lite対応機器の動作を確認するには、機器と通信するためのコントローラのソフトウェアが必要となります。SSNG for Node.jsは任意のECHONET Liteパケットを生成し送信することができます。また機器からの応答や通知のパケットを受信して表示します。

入手、使用方法は次のWebページを参照してください。
https://github.com/KAIT-HEMS/ssng-node

ツールの動作画面 (上記Webページから抜粋)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817840/aea50b92-41e6-fbc4-b1e3-a18a5bca266d.png)
ソースコードが公開されているので、ちょっとした機能追加も行えます。
例えば、データの送受信をNode.jsのソケットに対応していないUSB接続のWi-SUNを使用する場合、送受信処理のコードを変更することでWi-SUNでECHONET Lite通信が行えます。

## その③ EL Lighting など
その②でご紹介したSSNGは、16進数をダイレクトに入力したり、表示したりで、プロトコルに不慣れなECHONET Liteを使い始めたばかりの人には、使い方がイメージし難いかもしれません。リモコンのような感覚で、GUIを使用した照明やエアコン等を操作したい場合は次のツールがお薦めです。

* EL Lighting
https://apps.apple.com/jp/app/el-lighting/id1296697112

* EL AirConditioner
https://apps.apple.com/jp/app/el-airconditioner/id1521183064

* EL Blind
https://apps.apple.com/jp/app/el-blind/id1350662302

ここでは代表して照明機器を制御するEL Lightingのスクリーンショットを貼っておきます。(上記Webページからの抜粋)、他の機器は各ツールのWebページを参照してください。

 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817840/d3ff16dd-1302-738a-5802-2b2fa69cd052.png)

## 最後に

腕に覚えのある人であれば、「その②SSNG」や「その③EL Lightingなど」のような通信相手となるツールは、自作するケースも考えられますが、細かなところで、通信プロトコル仕様の解釈の間違いがあるかもしれず危険です。
そのため、相互接続性を確認には、第三者のツールや機器を使用することは有効です。

ECHONET Liteを推進する団体「エコーネットコンソーシアム」では、会員が機器や技術を持ち寄って相互接続を確認し実装情報を共有できる場としてプラグフェストを開催しています。あなたの所属している企業がエコーネットコンソーシアムの会員の場合、このような催しを、ご利用してみてはいかがでしょうか。
プラグフェストの詳細は下記のURLを参照してください。

https://echonet.jp/auth/plugfest

また、今回ご紹介したツールの個々の使用例は後日別途記事を書きたいと思っています。
【JavaScript】画像/写真/イラストから輪郭を抽出する【Sobelフィルタ】【切り絵風】


## 結論

Sobelフィルターを使う。

<img width=500 src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649673/a4dee386-6f31-960c-7e2e-0ad7723df2e1.png>

（2値化させるとより輪郭が分かりやすくなる。）
<img width=250 src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649673/f3c07b61-6213-3f8b-6708-07fab947889f.png>


Canvasに画像を貼り付けた後にimageDataを取得して、sobelフィルターをかけた後に、putImageDataしてちょ。

純粋なsobelフィルターは輪郭が白になるので以下のコードでは反転させています。

```js
function sobelFilter(imageData) {
    const data = imageData.data;
    const width = imageData.width;
    const height = imageData.height;

    for (let i = 0; i < data.length; i += 4) {
        const avg = (data[i] + data[i + 1] + data[i + 2]) / 3;
        data[i] = avg;
        data[i + 1] = avg;
        data[i + 2] = avg;
    }

    const sobelData = new Uint8ClampedArray(width * height);

    const kernelX = [
        [-1, 0, 1],
        [-2, 0, 2],
        [-1, 0, 1]
    ];
    const kernelY = [
        [-1, -2, -1],
        [0, 0, 0],
        [1, 2, 1]
    ];

    for (let y = 1; y < height - 1; y++) {
        for (let x = 1; x < width - 1; x++) {
            let pixelX = 0;
            let pixelY = 0;

            for (let ky = -1; ky <= 1; ky++) {
                for (let kx = -1; kx <= 1; kx++) {
                    const pixel = data[((y + ky) * width + (x + kx)) * 4];
                    pixelX += pixel * kernelX[ky + 1][kx + 1];
                    pixelY += pixel * kernelY[ky + 1][kx + 1];
                }
            }

            const magnitude = Math.round(Math.sqrt(pixelX * pixelX + pixelY * pixelY));
            sobelData[y * width + x] = magnitude;
        }
    }

    for (let y = 0; y < height; y++) {
        for (let x = 0; x < width; x++) {
            const idx = (y * width + x) * 4;
            const invertedMagnitude = 255 - sobelData[y * width + x];
            data[idx] = invertedMagnitude;
            data[idx + 1] = invertedMagnitude;
            data[idx + 2] = invertedMagnitude;
            data[idx + 3] = 255;
        }
    }
}
```

## サンプル

https://mogamoga1024.github.io/kirie/

## 輪郭抽出との出会いとなった記事

https://qiita.com/keiskimu/items/24456deeb6ef7665a6c1
Intel MacからApple Silicon Macへの移行時にHomebrewのバージョンの違いに注意


Intel MacからApple Silicon Macへの移行にはいくつかの注意点があります. その一つが、Homebrewのバージョンやインストール先の違いです. 私は移行後にIntel Macの設定が残っていたため、Rubyのインストール時にIntel Mac側のHomebrewで管理していたパッケージを使用しようとして完全にハマったので、この記事にその対策を記録します.

## Intel MacとApple Silicon Macでの違い

Intel MacとApple Silicon Macでは、Homebrewのインストール先ディレクトリが異なります.

•	Intel Mac:          `/usr/local`
•	Apple Silicon Mac:  `/opt/homebrew`

この違いにより、移行後にIntel Macの設定がApple Silicon Mac上で動作してしてしまうことがあります. Apple Silicon Macを使っているのに、`brew --prefix` で `/usr/local`と出力された場合は、Intel Mac版を参照しているので、以下の変更をしましょう.


## 変更方法

https://zenn.dev/nenenemo/articles/ccf95cafcd3d19#%E6%97%A2%E5%AD%98%E3%81%AEhomebrew%E3%81%AE%E5%89%8A%E9%99%A4%E3%81%99%E3%82%8B%E5%89%8D%E3%81%AB

### 1. Intel Mac用のHomebrewのバックアップ

まず、Intel Mac用のHomebrewパッケージのリストをバックアップします.

```
brew bundle dump --global
```

### 2. Intel Mac用のHomebrewを削除

```
export PATH=/usr/local/bin:${PATH}
brew uninstall $(brew list)
```

### 3. Silicon Mac用のHomebrewのインストール

```
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
```

完了するとターミナルに以下のコマンドを打ってパスを設定するように指示をされるのでそのまま打ちます.

```
echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> /Users/xxx/.zprofile
eval "$(/opt/homebrew/bin/brew shellenv)"
```

### 4. インストールの確認

```
brew --prefix
# 出力: /opt/homebrew
```

### 5.	バックアップしたパッケージの再インストール

```
brew bundle dump --global
```

もっと詳しく知りたい方は参考文献を閲覧してください.

### 参考文献

https://qiita.com/Shin-mfc/items/38b628e6e39ee7f8b54f

https://zenn.dev/nenenemo/articles/ccf95cafcd3d19

https://zenn.dev/teitei_tk/articles/bcb737d38fc867

https://chigusa-web.com/blog/homebrew/

https://note.com/ryugoo/n/nd1cf6fd824e3
使わない技術は忘れる

個人的「質はともかく継続する」１4日目です

## 使わない技術は忘れる

業務でも、業務外でもいろいろな技術を試すことがあります。
ちょっとしたツールのようなものを、勉強がてら経験の少ない言語や
フレームワークを使って作ることがあります。
でもそういった技術は頻繁に使うことがないので、
半年もすれば「あれ、このフレームワークでここを変更するのどうするんだっけ」
となってしまいます。
別のチームのヘルプに入った後や、プロジェクトが終わって時間が立ったりするのも同じ。
技術だけでなく、仕様も経緯もどんどん忘れていきます。
使わないから、忘れていくんですよね。

## メモを書くことである程度は防げる

そういうときのために、ドキュメントを書きます。
「昨日の自分は他人」と先輩に言われたことがありますが、
いまもこの金言を大事にしています。
そう、昨日の自分は他人で、半年前の自分は他人でさえないです。
そんなときに頼りになるのが、ドキュメントです。
ですが、ドキュメント、というとちょっとハードルが上がります。
つまり「めんどくさそう」が出てきます。
そこで、「メモ」を書きます。

やったこと、調べたサイト、画面キャプチャ、
考えたこと、愚痴、感想、なんでもいいです。
形式もどうでもいいです。
個人的には後から検索出来るようにmarkdownで書きますが、
職場環境によっては難しいでしょうから、
Excelでもワードでも、テキストファイルだっていいです。

とにかく、メモを残しておく。
きちんとしない、適当でいいから残しておく。
記憶のインデックスを残すような感じです。

## 「how」も大事だが「history」が大切

ドキュメントにはよく「方法」が書かれています。
もちろん職場によりけりですが。
個人的には「方法」のドキュメントも大事ですが、
なぜそうするのか、そうなっているのかの経緯、
「history」のほうが大切なんじゃないかと思ってます。
「how」は調べればなんとかなることが多いですが（closedの場合は例外)、
「history」は調べてもどうにもなりません。
その会社独自の、そのシステム独自の歴史なんて
AIも知らないしネットにも載ってませんから。
「忘れてしまうと取得出来ない情報」をできるだけ残すようにしてます。

## でも「how」も大事

とはいえ「how」も大事です。
ちょっと試してみたフレームワークで、
ちょっとだけカスタマイズした部分があったら、
その方法は残しておいたほうがいい。
調べればわかることではありますが、
調べるのに時間が掛かってしまう事が多いのです。

## なにがいいたいの？

- 作業のメモを残すこと
- 形式は気にしないこと
- 「history」を意識すること
- 「how」も残しておくこと
- でもやっぱり形式は気にせずとにかくメモを残すこと
- 「暑い」「アイス食べたい」でもいいからメモを残すこと

とにかく作業メモを取ること、おすすめです。
それでも使わない技術は忘れて行くんですよね。。。
yargsの位置引数の省略と引数名を使用する方法のメモ

# コマンドライン引数の覚書

コマンドラインって便利だけど、自分で作るとやっぱり面倒な事も多いですよね。
今回は、コマンドラインツールを作ると高確率で起きる面倒毎のメモを残しておこうと思います。

## 引数の処理は地味に面倒

毎度ツールを作る時に地味に面倒なのはコマンドライン引数を受ける時の処理です。
使い捨てのツールの場合は、process.argv[]を直接使うか、パラメータになる部分をハードコードしてしまえばいいんですが…。
今後も使うものは、使い方忘れる場合もあり、引数を調べるためにソースを読みたくないのでヘルプもしっかりしておきたいんですがこれが地味に面倒です。

## 面倒を解決するためのコマンドライン引数のパーサーのはずが…

コマンドライン引数の処理を簡略化したくて、ライブラリを使う事にしました。
調べた感じ、yargsというライブラリが人気の様なので今回はyargsを使用するようにしました。
そして、今回もしっかりハマりました。

## コマンドライン引数に名前を付けられるのですが、引数名が上手く使用できない。

沢山転がっている位置引数(?)を使用したサンプルの例
```
const argv = yargs(hideBin(process.argv))
	.positional('imagePath', { ... })
	.positional('isClip', { ...	})
	.demandCommand(1)
	.argv;
 
// 使用サンプル
somthingFunc(argv._[0], argv._[1]);
```

positional('imagePath',...)やpositional('isClip',...)で引数名付けているんだから
imagePathやisClipの名前を使ってやり取りしたいわけです。
こんな感じです。
```
somthingFunc(argv.imagePath, argv.isClip);
```

結局、面倒事はライブラリで楽をする予定でしたが余り楽は出来なかったです。

## 結論

色々試行錯誤して分かったことは、.command()を定義しないと引数の名前は使用できない様です。

内部処理を見てないので分からないですが、使う側としてpositionalの設定で使用方法定義しているのでそこはいい感じにして欲しかった。

ということで、以下が名前を使って動作する書き方になります。

```create_image.js
const yargs = require('yargs/yargs');
const { hideBin } = require('yargs/helpers');

// コマンドライン引数の処理
const argv = yargs(hideBin(process.argv))
	.command('* <imagePath> [isClip]')
	.positional('imagePath', {
		describe: '画像パスを指定してください',
		demandOption: true,
		type: 'string',
	})
	.positional('isClip', {
		describe: 'クリップを行うか',
		type: 'boolean',
		default: true,
	})
	.demandCommand(1)
	.argv;

// 使用サンプル
somthingFunc(argv.imagePath, argv.isClip);
```
【Docker】DockerでRailsのデバッグを実行する【Rails】

## やりたいこと
Dockerで実行しているRailsアプリケーションのデバッグを実行する

## なぜ行うか
設定なしにbinding.pryをソース内に記述しても止まらないため、以下の設定が必要。

## 方法
1. docker-compose.ymlに下記を追加

```yml:docker-compose.yml
web:
    # 以下を追加する
    tty: true
        stdin_open: true
```

    
# ターミナルで実行しているdockerにattachする

```docker:
# 起動しているdockerのコンテナ名を調べるため、以下を実行
$ docker ps
# 調べたコンテナ名を利用して、docker環境にattachする
$ docker attach コンテナ名
```

## 最後に
上記を行うとdocker環境でpry-byebugを利用したデバッグを利用できます。
Nonstop4d: Solusi Terbaik untuk Hiburan Online yang Aman dan Seru

Dalam era digital saat ini, hiburan online menjadi semakin populer di kalangan masyarakat. [Nonstop4d](https://slamminvinyl.co.uk/
) adalah salah satu platform terkemuka yang menawarkan berbagai bentuk hiburan online yang aman, nyaman, dan menyenangkan. Berikut ini adalah beberapa alasan mengapa Nonstop4d menjadi pilihan terbaik untuk hiburan online Anda.

Keunggulan Nonstop4d

1. Pilihan Permainan yang Beragam Nonstop4d menyediakan berbagai pilihan permainan yang bisa dinikmati oleh semua kalangan. Dengan pilihan yang beragam ini, pengguna memiliki fleksibilitas untuk memilih permainan yang sesuai dengan preferensi mereka.
2. Keamanan Terjamin Nonstop4d menempatkan keamanan sebagai prioritas utama. Dengan teknologi enkripsi terbaru dan sistem keamanan yang canggih, data pribadi dan aktivitas pengguna terlindungi dengan baik. Anda dapat menikmati hiburan dengan tenang tanpa khawatir mengenai keamanan data Anda.
3. Bonus dan Promosi Menarik Nonstop4d menawarkan berbagai bonus dan promosi menarik yang dapat meningkatkan pengalaman hiburan Anda. Mulai dari bonus selamat datang hingga hadiah spesial, semuanya dirancang untuk memberikan nilai tambah bagi para pengguna.
4. Layanan Pelanggan 24/7 Nonstop4d memiliki tim layanan pelanggan yang siap membantu Anda kapan saja. Dengan layanan 24 jam sehari, 7 hari seminggu, Anda dapat menghubungi tim dukungan kapan pun Anda membutuhkan bantuan atau memiliki pertanyaan.
5. Antarmuka Pengguna yang Ramah Nonstop4d dirancang dengan antarmuka yang mudah digunakan. Baik Anda seorang pemula maupun pengguna berpengalaman, Anda akan dengan mudah menemukan fitur yang Anda butuhkan dan menikmati pengalaman hiburan yang lancar.

Cara Bergabung dengan Nonstop4d

Bergabung dengan Nonstop4d sangatlah mudah dan cepat. Berikut adalah langkah-langkahnya:
1. Daftar Akun Kunjungi situs resmi Nonstop4d dan klik tombol 'Daftar'. Isi formulir pendaftaran dengan informasi yang diperlukan, seperti nama, alamat email, dan nomor telepon.
2. Verifikasi Akun Setelah mendaftar, Anda akan menerima email verifikasi. Klik tautan dalam email tersebut untuk mengaktifkan akun Anda.
3. Nikmati Hiburan Setelah akun Anda aktif, Anda dapat langsung menikmati berbagai permainan dan fitur hiburan yang tersedia di Nonstop4d. Jangan lupa untuk memanfaatkan bonus dan promosi yang ditawarkan untuk mendapatkan pengalaman yang lebih menyenangkan.

Kesimpulan

Nonstop4d adalah platform hiburan online yang menawarkan pengalaman yang aman, nyaman, dan menyenangkan. Dengan berbagai pilihan permainan, keamanan yang terjamin, bonus menarik, layanan pelanggan yang responsif, dan antarmuka pengguna yang ramah, Nonstop4d adalah pilihan terbaik bagi Anda yang ingin menikmati hiburan online. Bergabunglah sekarang dan nikmati semua keuntungan yang ditawarkan oleh Nonstop4d!
Anypoint StudioでXMLを読みやすくするために「Split multiple attributes each on a new line」を設定する方法

Anypoint StudioでXMLの可読性を向上させるために、複数の属性をそれぞれ新しい行に分割する設定を行うことができます。

## 設定

1. Anypoint Studioの「Settings」メニューを開きます。（Windowsの場合は「Preferences」）
1. XML -> XML Files -> Editorを開き、「Split multiple attributes each on a new line」にチェックを入れます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260307/7bc66466-14aa-d6ae-a98c-4ff589c363ae.png)

## 設定の効果

この設定を有効にすることで、XMLファイル内の要素が複数の属性を持つ場合、それぞれの属性が新しい行に分割されて表示されるようになります。例えば、以下のようなXMLが：

```xml
<book title="Effective Java" author="Joshua Bloch" publisher="Addison-Wesley" year="2008"/>
```
次のようにフォーマットされます：

```xml
<book
    title="Effective Java"
    author="Joshua Bloch"
    publisher="Addison-Wesley"
    year="2008"
/>
```

各属性が見やすくなり、特に大規模なXMLファイルを扱う場合に可読性が大幅に向上します。
AMPHPを実行できる環境を用意する

##  概要
PHPで非同期処理の実装を行いたかった。8.1で導入されたFibersが組み込まれており、使用感がよさそうだったAMPHPを使える環境を用意してみたのでまとめます。

## 環境構築
dockerでローカルのコンテナ内にミニマムのphp動作環境を作ります。

## dockerfile
phpとcomposerをいれる。
```dockerfile
# syntax=docker/dockerfile:1

FROM php:8.3.8-alpine

WORKDIR /app

# composer install
COPY --from=composer /usr/bin/composer /usr/bin/composer
```

## docker-compose.yml
```yml
version: "3.9"

services:
  app:
    build: ./
    stdin_open: true
    tty: true
    volumes:
      - .:/var/www/html
    ports:
      - 8011:80
```

## インストールと確認
```bash
docker compose up -d
docker compose exec app bash //コンテナに入る
php -v
composer -v
```

![スクリーンショット 2024-06-21 15.05.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254217/ab3d674e-7f65-cdb9-0b3f-d8877b5290f0.png)

ok!

## AMPHPのインストールと実行
公式通りにいきます。

https://amphp.org/installation

```bash
composer require amphp/amp
composer require revolt/event-loop
```

まんまコードをコピーして実行

![スクリーンショット 2024-06-21 20.28.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254217/6f9a62bf-a82e-3045-f273-05dce900b994.png)

doc通りに表示されました！非同期で遅延表示されるのが確認できます。

## 今回のソース
https://github.com/hoshima-ut/learning-amphp

こちらにまとめておきました。

## 最後に運動通信社について
運動通信社は「日本を世界が憧れるスポーツ大国にする」というビジョンを達成するべく、一緒に働く仲間を募集しています！
PMやアプリエンジニア、Webエンジニアなど色んな職種を募集しておりカジュアル面談大歓迎なので是非採用フォームよりご連絡ください！
ぜひ一緒に、自分たちも世の中もワクワクするサービスを作りましょう！

https://sportsbull.jp/about/#recruit
mail()関数でエンベロープFromを指定する

![php001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3668800/27e692d0-b598-c044-ec95-7527afce1888.png)

web制作でPHPを利用している方は多いのではないでしょうか？

実際、WordPressを始めとするCMSの多くはPHPで作成されております。

PHPではメール関数が用意されておりプログラムから簡単にメール送信を行う事が出来ます。

ですが、デフォルト設定のままメール送信を行うと、送信元が下記の様になります。

```
「実行ユーザー@サーバー名」
```

その為、場合によっては迷惑メールとして認識され拒否される可能性がございます。

また、利用ドメインとサーバー名が異なる場合、バウンスメール等も受信できなります。

そこで今回はメール関数を使用する際のエンベロープFromの設定方法をご紹介します。


## エンベロープFromとは

エンベロープFromとFromヘッダーは異なる役割がございます。

Fromヘッダーは、メール本文のヘッダー部分に含まれる送信者のアドレスの情報となっておりメールクライアントに表示される情報となります。

エンベロープFromはメール送信のSMTPセッション中に利用される情報となります。

その為、サーバー間でメール配送を行う場合は「エンベロープFrom」が送信元情報として扱われます。

PHPのメール関数をデフォルトのまま使用するとエンベロープFromは「実行ユーザー@サーバー名」となってしまいます。

## 基本的な使用方法

![php002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3668800/a1ed25d1-d712-6fea-4a0d-deb4a0c3756a.png)


mail()関数の基本的な使用方法は以下となります。

```
$to = 'to@example.com';
$subject = '件名';
$message = '内容';
$headers = 'From: sender@example.com';

$mail_sent = mail($to, $subject, $message, $headers);
```

上記の様に「to」「subject」「message」「headers」を指定しmail関数を実行する事でメール送信を行う事ができます。

詳細につきましては下記公式サイトをご確認よろしくお願い致します。

[mail()関数詳細](https://www.php.net/manual/ja/function.mail.php)

## エンベロープFromを指定するには

エンベロープFromを指定するには「-f」を指定し関数に組み込む必要があります。

今回のFROMアドレスである「ender@example.com」を指定する場合は以下となります。

```
-fsender@example.com
```

先程のプログラムに埋め込む場合は以下のようになります。

```
$to = 'to@example.com';
$subject = '件名';
$message = '内容';
$headers = 'From: sender@example.com';

$envelope = '-fsender@example.com';

$mail_sent = mail($to, $subject, $message, $headers);
```

以上で設定完了となります。

WordPress等のCMSを利用している場合は利用プラグイン等によりコントロールパネル上でエンベロープFromが指定できる場合がございます。
Cisco基本コマンド


## 設定モードへの移行
enable - 特権EXECモードに移行
configure terminal - グローバル設定モードに移行
exit - 設定モードから抜ける、またはひとつ上のモードに戻る
end - 特権EXECモードに戻る
## インターフェース設定
interface [インターフェース名] - インターフェース設定モードに移行
ip address [IPアドレス] [サブネットマスク] - インターフェースにIPアドレスを設定
no shutdown - インターフェースを有効化
shutdown - インターフェースを無効化
## ルーティング設定
ip route [宛先ネットワーク] [サブネットマスク] [次のホップIPアドレス] - スタティックルートを設定
router ospf [プロセスID] - OSPF設定モードに移行
network [ネットワークアドレス] [ワイルドカードマスク] area [エリア番号] - OSPFネットワークを設定
## VLAN設定
vlan [VLAN番号] - VLAN設定モードに移行
name [VLAN名] - VLANに名前を付ける
interface [インターフェース名] - インターフェース設定モードに移行
switchport mode access - インターフェースをアクセスポートに設定
switchport access vlan [VLAN番号] - インターフェースを特定のVLANに割り当て
確認コマンド
show running-config - 現在の設定を表示
show ip interface brief - インターフェースの簡易情報を表示
show vlan - VLANの設定情報を表示
show ip route - ルーティングテーブルを表示
show version - システム情報を表示
show interfaces - インターフェースの詳細情報を表示
## ネットワークの基本コマンド一覧

## 接続確認と経路追跡
ping [ホスト名またはIPアドレス] - ホストへの接続を確認
traceroute [ホスト名またはIPアドレス] - パケットの経路を追跡（Linux）
tracert [ホスト名またはIPアドレス] - パケットの経路を追跡（Windows）
## ネットワークインターフェース設定
ifconfig - ネットワークインターフェースの設定と表示（Linux）
ip addr show - ネットワークインターフェースの設定と表示（Linux）
ip link set [インターフェース名] up/down - ネットワークインターフェースの有効化/無効化（Linux）
ipconfig - ネットワークインターフェースの設定と表示（Windows）
ipconfig /renew - IPアドレスを更新（Windows）
ipconfig /release - IPアドレスを解放（Windows）
ルーティングテーブルの表示と設定
route - ルーティングテーブルの表示と操作（Linux）
ip route - ルーティングテーブルの表示と操作（Linux）
route print - ルーティングテーブルの表示（Windows）
route add - ルートを追加（Windows）
## ポートスキャンとサービス確認
nmap [ホスト名またはIPアドレス] - ポートスキャンを実行
netstat - ネットワーク接続、ルーティングテーブル、インターフェース統計などを表示
ss - netstatの代替コマンド（Linux）
## ファイル転送
scp [ユーザー名@ホスト]:[ファイルパス] [ローカルパス] - セキュアコピー（Linux）
rsync [オプション] [ソース] [ターゲット] - ファイルの同期（Linux）
## DNSと名前解決
nslookup [ホスト名またはIPアドレス] - DNS情報を表示
dig [ホスト名またはIPアドレス] - DNS情報を表示（Linux）
host [ホスト名またはIPアドレス] - DNS情報を表示（Linux）
その他のネットワークコマンド
wget [URL] - ファイルをダウンロード（Linux）
curl [URL] - データを転送（Linux）
telnet [ホスト名またはIPアドレス] [ポート番号] - Telnet接続を確立
ssh [ユーザー名@ホスト名またはIPアドレス] - SSH接続を確立
ftp [ホスト名またはIPアドレス] - FTP接続を確立
Databricks生成AIクックブック - 2.4. ガバナンスとLLMOps

[2\.4\. Governance and LLMops — Databricks Generative AI Cookbook](https://ai-cookbook.io/nbs/2-fundamentals-unstructured-llmops.html) [2024/6/21時点]の翻訳です。

:::note warn
本書は抄訳であり内容の正確性を保証するものではありません。正確な内容に関しては原文を参照ください。
:::

> [Databricks生成AIクックブック](https://qiita.com/taka_yayoi/items/36c51bce8f33a70cf204)のコンテンツです。


# 2.4. ガバナンスとLLMOps

## 2.4.1. ガバナンス

あなたの企業データとAI資産が適切なアクセスコントロールとロギングによって保護されるようにするためのガバナンスが必要となります。AIガバナンスの詳細な情報に関しては、[AIガバナンス](https://www.databricks.com/jp/product/machine-learning/lakehouse-ai-governance)をご覧ください。

## 2.4.2. LLMOps

LLMOps、より広範にはMLOpsはAIシステムのパフォーマンス、安定性、長期的な効率性を改善するためにデータ、コード、モデルを管理するためのプロセスと自動化に関するセットです。LLMOpsの詳細に関しては[Big Book of MLops](https://www.databricks.com/blog/big-book-mlops-updated-generative-ai)をご覧ください。

![](https://ai-cookbook.io/_images/5_img.png)

- [目次](https://qiita.com/taka_yayoi/items/36c51bce8f33a70cf204#%E7%9B%AE%E6%AC%A1)
- 前のセクション: [2.3. 評価とモニタリング](https://qiita.com/taka_yayoi/items/e4344fddbf3f1cea1f79)
- 次のセクション: [3. RAG品質のノブ](https://qiita.com/taka_yayoi/items/c5d63ebe767ec9833464)


### はじめてのDatabricks

[はじめてのDatabricks](https://qiita.com/taka_yayoi/items/8dc72d083edb879a5e5d)

### Databricks無料トライアル

[Databricks無料トライアル](https://databricks.com/jp/try-databricks)
PowerVC アンインストールで /etc/hosts から自身のエントリーが消える

#### はじめに

PowerVC アンインストールを行ったのちに、/etc/hosts から自身のエントリーが消えていたことに気づいたログです。


---


#### 環境


PowerVC 2.2.0 on RHEL ppc64le
　ホスト名 pvctest
　1 node クラスター構成

```
# cat /opt/ibm/powervc/version.properties
[2.2.0 Install]
name = IBM PowerVC
version = 2.2.0
build = 20231102-0930
oem = no
install-date = 2024-04-09
cloud_enabled = yes
cluster = pvc220
install_method = cluster
```

バージョン 2.2.0 で確認しましたが、別バージョン 2.0.2.1 でもアンインストール後に消えていました。


----

#### /etc/hosts でエントリー確認

```
# cat /etc/hosts 
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
xxx.xx.xxx.xxx	pvctest       #< PowerVC サーバー
````

pvctest がサーバー自分自身です。


----

#### アンインストールを実行

以下のコマンドでアンインストールを実行します。

```
# powervc-opsmgr uninstall -c pvc220
```


PowerVC docs: [Uninstalling ](https://www.ibm.com/docs/en/powervc-cloud/2.2.0?topic=uninstalling-)

ログは省略

アンインストール後の /etc/hosts 確認

```
# cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
```


対象のエントリーが消えていました...

----

#### uninstall playbook 確認

アンインストール処理で実行されていた下記の Ansible playbook 内に /etc/hosts エントリーを削除している箇所を見つけました。

**/opt/ibm/powervc-opsmgr/ansible/core/roles/pvc_removenode/tasks/pvc_removenode_powervc_uninstall_cluster.yml**

```
# cat /opt/ibm/powervc-opsmgr/ansible/core/roles/pvc_removenode/tasks/pvc_removenode_powervc_uninstall_cluster.yml

~ 省略 ~ 


- name: "{{ pvc_removenode_task_names.update_etchosts_after_remove_cluster }}"
  lineinfile:
    dest: '/etc/hosts'
    regexp: '{{ item }}'
    state: absent
  with_items: "{{ groups['controller'] }}"
  vars:
    ansible_python_interpreter: "{{ (ansible_distribution | lower in ['sles', 'sles_sap']) | ternary(python_36, ansible_python) }}"

```

with_items で groups['controller'] が指定されていますが、これがおそらくPowerVC管理ノード自身と思われます。

<br>
state: absent ...消去されていますね..


---

#### おわりに

アンインストール後に他の用途でサーバーを使用したい、再度PowerVC インストールを実行したいなどの場合にはお気をつけください。
【SwiftData】Query with dynamic properties in a View

結果を表示する子 View にて。

```swift
struct UserListView: View {
  @Query var users: [User]
  
  init(sort: SortDescriptor<User>) {
    _users = Query(sort: [sort])
```
こういうことですか。

# 🧑🏻‍💻 参考
https://android.benigumo.com/20240621/query-with-dynamic-properties/
キャリアに悩む人へ「キャリアの中で目的と手段が入れ替わる」

## はじめに

◆この記事は何？
エンジニアのキャリアについて、目的と手段の入れ替わりについて紹介する記事です。

◆対象は？
キャリアに悩むエンジニア

◆この記事のねらい
「キャリアの変化」について理解が少しでも深まれば幸いです。

## 先に結論
- キャリアの中で**目的と手段が入れ替わる**
- 私は目的が「機械学習」→「データサイエンス」→「アプリ開発」と入れ替わってきた
- 今の目的から**次のキャリアがなんとなく予想できる**

## 当初の目的がどこかに消える

> 私たちは日々の仕事のなかで、自分の目指していることが袋小路に入ってしまうことがよくある。そんなとき、冷静に原因を分析してみると、いつしか当初の目的がどこかに消えてしまっていて、手段が目的にすり替わり、それに振り回されていたことに気づく。

これは[『働くこと原論』](https://careerscape.lekumo.biz/genron/2013/12/post-6f71.html)に出てくる一節です。

私は、機械学習に強い興味があり、機械学習を目的に働いていました。
いつの間にか、機械学習が目的であったことを忘れ、それを手段にしてデータサイエンスに没頭するようになりました。
そのデータサイエンスも今では手段となっています。

私のキャリアは次のように図示できます。

![キャリア.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/616496/ce0894b2-dda9-407d-1e40-8416836caf21.png)

現在は、データサイエンスと関わりの強いアプリケーションをつくれるようになりました。

このように整理すると、未来をなんとなく予想できます。

## 今の目的からこれからのキャリアを少しでも予想する

「10年後どうなっていたいか？」と聞かれても、自分でも良く分かりません。

しかし上図の流れから予想すると、「データサイエンス系アプリケーション開発」を手段にして、事業創出が目的になるのではと考えています。

全く分からなかった自分のこれからのキャリアについて、少しですが理解が進みました。

私にとっては大きな一歩です。

## おわりに

この記事では、キャリアの中で目的と手段が入れ替わることを紹介しました。

自分のキャリアに悩む方の参考になれば幸いです。

## 参考

[『働くこと原論』](https://careerscape.lekumo.biz/genron/2013/12/post-6f71.html)
Raspberry Pi Pico用micro SDカード基板つくった

![_DSC0682.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108691/f41559d3-21f5-cab9-5d52-c6db0970a1f9.jpeg)
↑これが
こうなる↓
![_DSC0691.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108691/ae5a233a-3a22-c6d6-316a-388872a62f2f.jpeg)

ブレッドボードやテストワイヤ配線は手軽に試せて便利ですが、扱う回路があるていど定まったあとは取り回しが悪かったりウッカリ配線を外してしまったりと面倒です。面倒なのでプリント基板を作りました。生まれてこのかたプリント基板(以下PCB)を作ったことがなかったので電子回路設計ソフトはお手軽な[Fritzing](https://fritzing.org)、製造は[PCBWay](https://www.pcbway.com)です。

これまでRaspberry Pi Picoと[Adafruit MicroSD card breakout board+](https://www.adafruit.com/product/254)をスルーホール用のテストワイヤで配線した回路を利用していましたが、PCB発注のためにFritzingで回路を作図しました。部品ライブラリからRaspberry Pi PicoとマイクロSDカードコネクタを選択して仮想ブレッドボードに配置して配線。
![breadboard.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108691/75617028-b393-19bb-ea4b-6a45eec60a66.png)

回路図で接続に誤りがないか確認して
![circuit.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108691/66486d4c-7a8c-5741-db93-65248828f825.png)

PCBレイアウト画面で部品の配置とルーティングを調整します。ルーティングは自動ルーティングでおまかせ。
![pcb.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108691/f6312a37-32bc-5cc4-5478-e5120ef77c25.png)

今回はRaspberry Pi Picoの背面に直接はんだ付けする同寸法の2層基盤を作成しました。micro SDカードコネクタは端に寄せた方が取り回しが良くなりますが、Fritzingは製図できるのが2層までなのでコネクタ位置に妥協が必要でした。部品の配置がタイトすぎると配線する余地がなくなるんですね。

設計した回路はアプリからPCBWayに直接アップロードして、レビュー・発注までいけます。ファイル形式の調整とか面倒なことが一切なくてとても便利。5枚注文して、初回割引で送料込み約17ドル。注文後24時間で発送。

micro SDソケットは[microSD Socket for Transflash](https://www.sparkfun.com/products/127)を選びました。届いたソケットは写真と違く、開口部が大きくなっていて半田付けしやすく良かったです。完成したPCBの期待通りの小ささに満足感高いです。
![_DSC0692.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108691/59cfa847-6e79-c96e-116d-e4bb53110eeb.jpeg)

従来のテストワイヤ配線はPico〜SDカード間SPIボーレートを28MHzまでしか上げられませんでしたが、PCBにすることで48MHzまでいけるようになりました。1.7倍の高速化。

こういうモノの常で、発注した瞬間になぜだかミスに気がつくものですが、「フォームファクタ最小で安定したmicro SDカードSPI接続Picoを確保する」という自分の要件は満たせたのでOK。
課題（022）進捗

お疲れ様です。

昨日報告した課題（022）の現状報告です。
とりあえず、レスポンシブ対応以外は完了しました。あとはメディアクエリでレスポンシブ対応を設定して、見本と見比べて提出の流れです:computer:

![スクリーンショット 2024-06-21 105043.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3810013/6b412719-eb7e-73a7-50a3-750b0a78c42b.png)
これはほぼ始めの方です。
ここに border-bottom などを追加し、指定されたコードをcssに書いていきます。
<br>
そして、現在苦戦しているのがこちら。
![スクリーンショット 2024-06-21 163457.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3810013/70bb354d-0f91-be14-b91e-2e7e5da5ff12.png)
指示があるのは、2行目p の1文字目のみ太字と文字色指定するようにとなっており、 **first-letter** と **nth-of-type()** を組み合わせて実装するとのことですが、1行目の1文字目も変わってしまう…
言っている意味は分かるのですが、なかなか実現できない…！
調べる前に、試しにいろいろ書き換えたりしたのですが、2行目すべてが太字になってしまったりして、画像の状態が一番おしい状態ですが、どうすれば…
chatGPT先生にお世話になろうと思います:sweat_smile:
用語集が作れるくらいにはチームの会話量が増えていた

# はじめに

皆さんはチームメンバーと開発をする際、どのような会話をされていますか？
今回は私のチームで良く使われる用語を一部まとめてみました。参考にならないかもしれませんが楽しい雰囲気が少しでも伝わればと思います。

# 大谷またホームラン打ったらしいですね

解説：主に休憩時に使用。毎日のようにホームラン打っているので会話デッキ常連カード。大谷選手のようにビッグにならなきゃ。


# 帰りますか～

解説：作業のキリがついた時に使用。猛者はデイリー後に使用する。張りつめずに気楽に開発しよう。

# 散らばっていますね…ロードポーネグリフのように

解説：コードを範囲検索して多くのファイルでヒットしたときに使用。すべてを修正したその先にはラフテルが。

# これでいけるやろ！ポチ～～！

解説：デプロイコマンド実行時に使用。フラグが立つので大体エラーが出る

# キレイキレイしてコミプしましょう

解説：実装完了した時に使用。変更点を確認してcommitとpushしましょうの略。

# 召喚魔法を使いますか

解説：助っ人を呼ぶ時に使用。「お疲れ様です！ほげほげで困っているのでふがふがさんを召喚してもよろしいでしょうか？」という風にふがふがさんにお願いしたり。

# 何もないがありますね

解説：本来画面に表示されるべきものが表示されなかったときに使用。

# でかすぎんだろ…

解説：変更点の多いマージリクエストが作成されたときに使用。某テニスの画像と共に使用。これまで3回使用。


# 分身の術を使う時がきました

解説：他案件も担当する際に使用。分身すればスイッチングコストはゼロ。

# パラレルワールドにいました

解説：勘違いしていた時に使用。パラレルワールドにいたなら仕方ない。

# 良い週末を

解説：金曜日の定時間際に使用。一週間頑張ったことをお互いに称え、来週も頑張りましょうという意。


# おわりに
日々楽しく開発できています。