OmniAICreator/Qiita-1.07M huggingface dataset:
LINE DeveloppersコンソールからMessaging APIチャネルを作成できなくなったので、代替方法を試してみた

https://www.ryucom.co.jp/blog/aws/4713/

こちらのブログを見て実行したものの、2024/09/04にLINE APIの仕様変更があったため、備忘録として記載します。

プロバイダの作成までは引用元のブログ通りで実行可能です。
しかしMessagins APIチャネルの作成はDevelopperコンソールからではなく、LINE Official Account Manager上でAPIの利用を有効化する必要があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3957489/ef20b155-fe7b-8331-f0b8-3fa532412123.png)

添付画像のURLは以下
https://developers.line.biz/ja/docs/messaging-api/getting-started/#create-oa-check

これによると
1. LINE公式アカウントの作成
1. LINE公式アカウントでMessaging APIの有効化
が必要になります。

実際に登録した後の画面は以下のようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3957489/3033cfe5-111f-fbe9-448f-4fbfea1e8f6d.png)

現在はチャットがオフになっていますので、クリックしてチャット機能をオンにします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3957489/7cef5ce8-fe4e-6b77-8dbc-6bc67cd7d4c4.png)

初期は応答設定に入るため、MessagingAPIをクリックしてページ遷移後、Messaging APIを利用するをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3957489/249631ec-14e2-bbb5-c874-9266d6b09dca.png)

プロバイダがあればそちらを選択し、ない場合は作成します。
つまり文頭で提示のページではプロバイダーを先に登録していましたが、この時点で登録しても問題ありません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3957489/9b09705f-5a94-cece-1b61-10a9570f175b.png)

公式の注意喚起として以下の点が挙げられています。
プロバイダの変更ができないことに起因する問題が発生しうるので、そこを注意するようにとのことです。
>プロバイダー選択時の注意
一度、LINE公式アカウントを管理するプロバイダーを選択すると、後から別のプロバイダーに変更したり、Messaging APIとの連携を解除したりすることはできません。

> プロバイダー選択時に特に注意が必要なケース
たとえば、以下のような場合には特に注意してください。
チャネルとプロバイダーを別々の個人または企業が管理している。
1つのプロバイダー配下に、相互に関係がないサービスや企業のチャネルを作成する。
チャネルの運用ツール等を運営するサービス（企業）が管理するプロバイダーの配下にチャネルを作成する。
このようなケースでは、後からチャネルをプロバイダー間で移動できないことや、プロバイダーごとに異なるユーザーIDが割り当てられることに起因して、将来的に問題が発生する可能性があります。そのリスクを十分検討した上で、適切なプロバイダーを選択してください。

#2-2. LINE Developersコ


プロバイダのプライバシーポリシーと利用規約の登録を求められますが、たぶん現時点でする必要はないと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3957489/d7467635-0b2f-2a9e-b2b3-b58805731785.png)

これが完了したらMessagin APIのステータスが利用中になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3957489/ac1a7fef-9183-64f3-07b1-9637a5a2d85e.png)
新人が質問する心理的なハードルを超え、効果的に質問できるようになるためのポイント

「質問していいよ」と言われても、なかなか質問できないのはいろいろな理由がありますよね。

---

たとえば、**自分の無知をさらけ出したくないという気持ち**
- 「こんな基本的なことを聞いたら、どう思われるだろう」という不安。  
- 周囲からの評価や「できない人」と見られることへの恐れ。  
---

たとえば、**自分で解決すべきだというプレッシャー**
- 「これくらいは自力で解決すべき」という思い込み。  
- 先輩や上司の負担になりたくないという遠慮の気持ち。  
---

たとえば、**質問の仕方がわからない**
- 問題をどう整理し、どのように聞けばよいかが分からず、ためらってしまう。  
- 漠然とした悩みや疑問を具体的な質問に変換するスキルが未熟。  

---
などなど。

ひとりで考えても沼にハマって時間が溶けたという経験をして少しずつ改善されていくこともあるとおもいますが、私自身が１年目のとき頭に入れておけばもっとスムーズだったのでは？とおもうポイントをまとめます。
後半部分では「メンターや先輩の視点」から相談しやすい空気づくりや関係性構築を促進するポイントもまとめました。

## 質問の重要性を理解する
- **時間は有限である**  
  自分で解決に時間をかけすぎることはチーム全体の効率低下につながることを認識する。  
- **経験を積んだ人の知見を活用する**  
  質問することで、短時間でより良い解決策にたどり着ける。  

## 質問しやすい環境を作るための心構え
1. **質問は学びの一環であると認識する**  
   質問することは「できない自分を見せる」ことではなく、「学びのプロセスを加速させる行為」だと理解する
   
2. **相手の時間を意識し、簡潔に伝える**  
   質問を準備する際にはポイントを整理し、的確に伝えることで相手の負担を減らす

3. **失敗を恐れずにチャレンジする**  
   新人が間違った質問をしても、それは成長の過程と捉える


## 質問するための具体的なステップ
1. **まずは「3つの壁」を意識する**  
   - 自分で調べてみる  
   - ドキュメントやコードの関連箇所を確認する  
   - 解決のために試行錯誤を1回してみる  
2. **調べた内容と現状を整理する**  
   - 「〇〇を調べたが、解決できなかった」  
   - 「〇〇を試したが、このエラーで止まっている」  
   といった形で背景情報を簡潔にまとめる。
3. **質問する内容を明確にする**  
   - 具体的な問題と、期待している答え（アドバイスか解決策か）を明らかにする
4. **質問のタイミングを考える**  
   - チームや指導担当が質問を受けやすい「ゴールデンタイム」を把握し、効率よく質問を行う


## 心理的なハードルを越えるためのヒント

- **「先輩を困らせないために質問する」視点を持つ**  
  自分で迷い続けるより、早く質問して問題を共有する方がチームに貢献できる。  
- **小さな質問から始める**  
  些細なことでも質問を重ねることで、質問に対する抵抗感を減らす。  
- **「質問しないことで迷惑をかける」視点を持つ**  
  解決に時間がかかることで進捗が遅れるリスクを意識する。  

## 新人が心がけると良いこと
- **質問の練習をする**  
  毎日1つは誰かに質問する習慣をつけることで、心理的なハードルを下げる
- **質問の答えをチームに共有する**  
  学んだことを他のメンバーと共有することで、チームの知見も蓄積される  
- **小さな成功体験を積む**  
  質問することで得た成功体験を意識し、自信を深める


## 新人が質問しやすい環境を作るためのチームの工夫
1. **オープンドアポリシーの徹底**
メンターやメンバーは「いつでも質問していいよ」という雰囲気を日頃から伝える。

1. **雑談や日常的な対話を増やす**
コミュニケーションを活発化させることで心理的安全性を高め、新人が遠慮なく話しかけられる空気を作る。

1. **質問のハードルを下げる対応**
「いい質問ですね」とポジティブなフィードバックを心がける。
「これ知らなかったの？」というような否定的な言葉を使わない。

1. **定期的な振り返りの時間を設ける**
「最近困ったことがある？」など、新人が話しやすい場を意図的に作る。
週次や月次でメンターと1対1の面談を設ける。

1. **適度に放置しつつ見守る**
新人が自力で進める時間を尊重しつつ、適宜フォローに入れる体制を意識する。

1. **「初心者の視点」を尊重する**
新人が質問をしやすい空気感を作るために、「教える側が学ぶ」姿勢を示す。
新人の質問を「自分たちの改善につながる視点」として捉える。


## 新人とメンターそれぞれの視点での要点

https://pub.jmam.co.jp/book/b458318.html

### 新人の視点での要点
1. **積極的なコミュニケーションの重要性**
チーム内での雑談や相談を通じて、信頼関係を築き、円滑な業務遂行につなげる。

1. **自己成長の意識**
日々の業務やフィードバックを自己成長の機会と捉え、学び続ける姿勢を持つ。

1. **チームへの貢献意識**
自分の役割を理解し、チーム全体の成果に貢献する意識を持つ。

## メンターの視点での要点
1. **オープンなコミュニケーションの促進**
新人が気軽に相談や質問ができる環境を整え、心理的安全性を確保する。

1. **フィードバックの質とタイミング**
適切なタイミングで建設的なフィードバックを提供し、新人の成長をサポートする。

1. **チーム文化の醸成**
雑談や相談を組み合わせた「ザッソウ」の文化を取り入れ、チームの連携を強化する。

## さいごに
ひとつでも心理的ハードルを超えるヒントになれば幸いです。
VS Codeの拡張機能開発でviteを導入する

この記事はHRBrain Advent Calendar 2024 14日目の記事です。

https://qiita.com/advent-calendar/2024/hrbrain

## はじめに
[yakiniku0220](https://twitter.com/yakiniku040220)です。
今年から始めたVSCodeの拡張機能の開発でviteを入れたのでそのことに関して記事にしようと思いました。

VSCodeのセットアップに関しては以前記事にしているのでそちらを参考にしてみてください。

https://qiita.com/yakiniku0220/items/14b60a66530d70d261a5#vs-code%E3%81%AE%E9%96%8B%E7%99%BA%E7%92%B0%E5%A2%83%E3%81%AEsetup

## viteをinstallする
まず初めにviteをinstallします。

:::note warn
他のbundlerがinstallされている場合は事前に消しておくと良いです。
:::


```terminal
yarn add --dev vite vite-plugin-node
```

## configファイルを作成する。
次にconfigファイルを作成します。
以下コードです。

```ts
import { defineConfig } from "vite";

export default defineConfig({
  build: {
    lib: {
      entry: "src/extension.ts",
      name: "extension",
      formats: ["cjs"], // CommonJS形式で出力
      fileName: () => "extension.js",
    },
    rollupOptions: {
      external: ["vscode"],
    },
    sourcemap: true,
  },
});
```

設定は以上です。


## 動作確認
実際にcompileして動かしてみます。

![画面収録-2024-12-18-11.44.36.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271450/0f25ca7f-a1e7-8cee-f259-682efc4d5dd9.gif)

このような感じでWebviewにてgifが表示されたことが確認できました。

## まとめ
今回はviteを導入してみましたが、導入が非常に楽でした。
今個人開発している拡張機能の方でもbundlerをviteに移行してみようと思いました。
今回作ったサンプルコードは以下にcommitしているので参考にしてみてください。

https://github.com/ebarakazuhiro/blog/tree/main/20241214


## 最後に
株式会社HRBrainでは新しいメンバーを募集中です。
興味がある方は下記のリンクから宜しくお願い致します。

https://www.hrbrain.co.jp/recruit
【個人開発】好きな音楽を簡単に共有できるWebアプリ「Meesic」を紹介します！

## はじめに
初めまして、Yuma Yoshidaと申します。
現在はSES企業に所属し、バックエンドエンジニアを目指しています。

少し前のことですが、2024年1月から3月末までの3ヶ月間[レバテックキャンプ](https://lp.camp.levtech.jp)というプログラミングスクールでPHPやLaravelなどを学習していました。

その成果物として作成した、好きな音楽を簡単に共有できるWebアプリ[Meesic](https://meesic.me)を紹介します🎉

## Meesicとは

[Meesic](https://meesic.me)は、好きなアーティストのリストを作成し、簡単に共有することができるWebアプリケーションです。

![46C6981D-C525-42F4-AD1A-EE861DFDCA7D.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626956/4246cd0e-0af6-a374-84c5-39883c50a4b4.png)

### URL

https://meesic.me

### GitHubリポジトリ

https://github.com/yyoshidaweb/meesic

## 使い方
1. 編集ページの検索フォームからアーティストを検索
1. 検索結果の中から好きなアーティストをアーティストリストに追加


そして、`ホーム`タブのURLを共有することでアーティストリストを簡単に共有できます。

![](https://gyazo.com/8b5428fba9b2b251d9bbcd3a1fb3fedd.gif)

### 作成経緯
音楽関連のWebアプリを開発したいと考える中で、最初に思い浮かんだアイデアは「バンドリスト」というサービスでした。そこで、既に存在しているか確認するため、Google検索したところ1件のYahoo知恵袋の質問がヒットしました。

https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1088885600

この回答の中では以下のWebアプリが紹介されていましたが、もう機能していないようでした。

http://aph.jp/

また、最近[POTOFU](https://potofu.me/ja)や[lit.link](https://lit.link/)などのSNSリンクまとめサービスが普及し始めているので、これらのサービスのように好きな音楽のリストを簡単に共有できることを目指して作り始めました。

### 技術構成
#### フロント・クライアント技術
- HTML
- CSS
    - Tailwind CSS
- JavaScript

#### サーバーサイド技術
- PHP 8.2.16
    - Laravel 10.43.0

#### DB
- MariaDB

#### インフラ/その他専門技術
- Amazon Lightsail
- Spotify Web API

### 工夫した点
#### Spotify Web APIとの連携
アーティスト追加時、Spotifyの各アーティストに紐づいているIDのみをデータベースに保存しておき、アーティスト名やアーティスト画像などの詳細なデータは、Spotify Web APIからアーティストデータを取得することで、アーティスト情報を正確に検索・保存し、常に正しい音楽情報を共有できるようにしました。

この仕様は便利な反面、Spotifyに登録されているアーティストしか追加できないという問題があります。そこで、アーティスト検索フォームの下にアーティスト名を手入力で追加するフォームも用意しました。

#### ゲストログイン機能
新規登録する手間を省く目的でゲストログイン機能を実装しました。

実装した理由としては、このMeesicというWebアプリはポートフォリオとして公開する予定だったため、メインユーザーは採用担当者の方であると考えたからです。

ゲストログイン機能は以下のような仕様にしました。

#### ゲストログイン機能の仕様
##### ゲストログインボタンをクリックした時
1. ゲストユーザーが新規作成される
1. 作成されたゲストユーザーでログインする

さらに、ゲストユーザーはプロフィールの編集はできないように権限を設定しました。

#### ゲストログイン機能で工夫した点
##### ゲストユーザーが増え続けないようにした
ゲストユーザーを新規作成する仕様にした場合、使用されていないゲストユーザーのデータが増え続けるという問題がありました。
そこで、ゲストユーザーの自動削除機能を実装しました。

##### ゲストユーザーの自動削除の仕様
ゲストユーザーの削除は以下のような流れで、cronジョブとして自動実行されます。
具体的には、cronジョブがLaravelのschedule機能の`prune`メソッドを呼び出すという仕様です。
1. ゲストユーザーを自動削除するための`prune`メソッドが1日1回のスケジュールで実行される
1. `prune`メソッドが実行された時点で、作成後3時間が経過しているゲストユーザーは削除される

### 今後の課題
- パスワードリセットができない
    - 現在、パスワードを忘れた場合ログインできなくなってしまうのでメール認証を可能にして改善したい
- アーティストが追加した順にしか並ばない
    - 好き度順に並び替えたり、ジャンルごとに並び替えたりできるようにしたい

### 今後の展望
将来的にはユーザー同士の音楽の好みをマッチングする機能や、おすすめの音楽をレコメンドする機能などを追加したいです。

### さいごに
最後までお読みいただきありがとうございました！
もし興味がありましたらゲストログイン機能を試してみてください🤗

#### URL

https://meesic.me

#### GitHubリポジトリ

https://github.com/yyoshidaweb/meesic
Unity 用の Zenoh プラグインを作りました

## はじめに

本記事はZenohアドベントカレンダーの22日目の記事です。

https://qiita.com/advent-calendar/2024/zenoh

[Zenoh プロジェクト](https://github.com/eclipse-zenoh/)の中には [zenoh-csharp](https://github.com/eclipse-zenoh/zenoh-csharp) というレポジトリがあるのですが、これがもうずいぶん長いことメンテされてなくて、最近のバージョンの Zenoh との組み合わせではもはや動かなくなっていました。

Zenoh の特徴の一つあるブローカーレスの Pub/Sub に魅力を感じている勢としては、ぜひ Unity からも使いたいということで今回自作してみました。

## 作ったもの

今回作ったものとその使い方は GitHub で公開したのでご参照ください。
https://github.com/comoc/zenoh-pub-sub-for-unity

[zenoh-cpp](https://github.com/eclipse-zenoh/zenoh-cpp) が提供する API を Unity のネイティブプラグインから呼べるようにしたことで、Unity の C# スクリプトで文字列の Pub/Sub を実現しました。

## 参考

[ROS 2 のトピックを Zenoh でブリッジして TouchDesigner でサブスクライブする](https://qiita.com/comocc/items/448deee5a0bf82b586ec)
以前書いた記事です。

それでは良いお年と楽しい Zenoh & Unity ライフを！
コールセンター/CRM デモ＆コンファレンス 2024 in 東京 行ってみた

## 概要
「コールセンター/CRM デモ＆コンファレンス 2024 in 東京」は、最新のコールセンター技術やCRMソリューションを紹介する年次イベントです。業界のリーダーや専門家が集まり、基調講演やデモ、ネットワーキングの機会が提供されました。詳細は公式サイト[こちら](https://www.callcenter-japan.com/tokyo/)をご覧ください。

## 参加背景
コンタクトセンター案件に携わっており、市場調査を行う必要がありました。業界内で権威あるイベントとして位置付けられており、最新の市場動向・競合分析・技術トレンドが一挙に収集できることからこのイベントへ参加しました。目的は、市場調査です。
170の出展企業のうち「コンタクトセンタープラットフォーム」に該当する56企業への調査を行うことが目標でした。

## 準備
56企業への調査項目として以下を設定しました。○ の選択肢は指定なし
| 項目 | 選択肢 | 説明 |
|:-:|:-:|:-:|
| ベンダ種別  | SIベンダ、製品ベンダ、クラウドベンダ  |  - |
| 規模  | ○  |  何席に対応しているか |
| 顧客からの要望  | オンプレ、クラウド、両方  | -  |
| 顧客から求められる機能  |  ○ | -  |
| 強み  | ○  | -  |

## 結果
2日間で70社への調査を行うことができました。行動は以下です。

### 1日目
初めてのカンファレンスということでチームメンバーと待ち合わせをして向かいました。
AM(2h):チームメンバーとブース巡り。チームメンバーのお知り合いメインで周ったため話がしやすい
PM(4h):引き続き先輩社員とブース巡り。途中から離脱して目星を付けていたブースへ個人で周る

### 2日目
下の階から網羅的にひたすら周る。ローラーしていく。

## 調査まとめ

■ **市場の動向** ：
・	AIやオムニチャネル対応が急速に進んでおり、独自機能で競争している 。
・	顧客の要求はPBX、IVRや通話録音が当たり前になり、サービスの品質とリードタイム が重要視されている。
・	顧客体験の向上に注力している企業が多い。
・	小中企業向けではコストを削減し、大企業向けではコストより機能を重視している。
・	AIを活用したチャットボットを導入している企業が増加している。
・	専門のノウハウを持つ外部パートナーと協力を強化している。

## 学んだこと

**コミュニケーションの重要性** ：
イベントに参加して、多くの業界関係者と直接交流することの価値を実感しました。新卒エンジニアとして、他部門とのコミュニケーション能力を高めることが、知見を広げることに繋がると感じました。

**ネットワーキングの力** ：
多くの企業や専門家と話すことで、自分の知識や視野が広がるとともに、新たな人脈を築くことの重要性を学びました。これにより、将来のキャリア形成にも役立つと考えました。

**最新技術のトレンド** ：
イベントを通じて、AIやオムニチャネル対応の最新技術について学ぶことができました。常に最新の技術に興味を持ち、自己研鑽を続けることの重要性を再認識しました。

## 振り返り

今回事前準備として用意していたものは改良の余地をもつことがわかりました。情報整理をした際に選択肢なしで設定していた項目の集計にかなり手間がかかりました。今回のように多くの企業を周る計画があるのであれば、始めから選択肢を固定することが良いと学びました。聞く際の時間短縮にもなり、集計時の時間短縮にもなります。

最後に。カンファレンス会場は人が多く、熱気があるため適度な休息は必須です。
Pythonを基礎から学ぶその5　デスクトップのアプリを作るその3

この記事は、[JavaとPythonを基礎から学びたい私のための Advent Calendar 2024](https://qiita.com/advent-calendar/2024/aruhitonocalendar)の18日目の記事です。
アプリっぽくしていきます

# ボタンを押したときの動作
ボタンなので、押したときに何かが起こるようにします。まずはボタンを押したときに文字が出てくるようにします。
### commandを使う方法

```
def ClickEvent():
    label2=tk.Label(text='ボタン押したな',foreground='#00fa9a')
    label2.pack(padx=30,pady=10)   
 
button=tk.Button(text='ボタン',command=ClickEvent)
button.pack(padx=30,pady=20)

```
ボタンを押すとbuttonの()内のcommandが発動して、その上のClickEventが呼ばれます。今回はボタンが押されたときにメッセージを出すようにしています。

ちなみにdefはdefine(定義)のようです。Tabキーで右にずらした（インデント）文章がdefの内容です。

### bindを使う方法
ボタンを押したときのイベントは、bindを使うことでも設定できるみたいです。こちらは先ほどのcommandと違い、クリックの種類やマウスカーソルが対象物上に存在するかなど様々なイベントを起こせます。
ただしtkinterのボタンでは、クリックのイベントが右クリックしかできませんでした。マウスカーソルが対象物内に入ってきたかなどはうまく動作するようです。
追加した文です
```
def leftClick(event):
   # Left=Left+1
    label2=tk.Label(text='左')
    label2.pack(padx=10,pady=20)
def mouseEnter(event):
    #Right=Right+1
    label3=tk.Label(text='マウスカーソルがやってきました')
    label3.pack(padx=50,pady=20)
 
button=tk.Button(text='クリックかカーソル移動')
button.bind("<Button-1>",leftClick)
button.bind("<Enter>",mouseEnter)
button.pack(padx=30,pady=30)
```
bindの（）内、,の左側がイベントの種類（ボタンが押された、マウスカーソルが来たなど）です。"<>"で囲みます。右側はイベントが発生したときに呼ばれるものになります。
tkinterで動かせるもの一覧
| イベントの種類 | 説明 |
|:-:|:-:|
| Button-1  | 左クリック（押し込んだ時）  |
| ButtonRelease-1  | 左クリック後、ボタンが離れた時  |
| Enter  | マウスカーソルが対象物に来た時  |
| Leave  | マウスカーソルが対象物から離れた時  |
| Motion  | マウスカーソルが対象物上で動いた時  |

tkinterで使う以外であれば、うえで紹介した以外にもいろいろなものがあるようです。
これでボタンを動かすことができます。
# 文字入力できるようにする
文字も行けるようです。これができると、例えば数字を入力してボタンを押すと瞬時に計算してくれる電卓のようなものも作れそうです。
### Text()を使用する
```
txt=tk.Text()
txt.pack(padx=30,pady=60)
```
これで文字が入力できるフィールドが用意されます。また、入力された文字は
```
inputtxt=txt.get(1.0,tk.END)
```
こんな感じでgetを用いることで取得可能なようです
<b>このgetの文は必要なときに使ってください。</b>getされるタイミングは、この処理が行われる瞬間でした。テキストエリアを作成したときに一緒に書いても反応しません。
自分の場合は、ボタンが押されたときに文字がgetされるようにしました。
```
txt=tk.Text()
txt.pack(padx=30,pady=60)
def leftClick(event):
    inputtxt=txt.get(1.0,tk.END)
    label2=tk.Label(text='入力された文字:'+inputtxt)
    label2.pack(padx=10,pady=20)
```
こんな感じです。ちなみに（）内、","の左側の1.0はget開始位置です。ここでは1.0なので1行目０文字目という意味です。","の左側は終了位置のようです。ENDで最後まで受け付けてくれるみたいです。
### Entry()を使用する
先ほどのtextとは異なり、1行の入力ができるものです。webサイトとかによくある、名前入力欄みたいなものです。
```
txt=tk.Entry(window)
txt.pack(padx=30,pady=60)
```
Entry()の（）内、windowは最初に設定したwindow=tk.Tk()のものです。なくても動くようですが、ないよりはあった方がいいと思います。
文字を取得する場合は、
```
inputtxt=txt.get()
```
先ほどと同じくgetで行けました。今回は（）内が空であっても取得してくれるみたいです。
# まとめ
ボタンを押したときの処理の仕方にもさまざまな種類がある。また、文字を入力したり入力された文字を受け取ったりする処理の仕方もまたいろいろ存在していた。
# 参考文献

https://www.school.ctc-g.co.jp/columns/hishinuma/hishinuma27.html

https://blog.narito.ninja/detail/100/

https://myroad.hatenablog.com/entry/2020/05/14/230000

https://python-work.com/tkinter-button/
【学習】deviseの理解向上（i18nについて）

## はじめに
下記Qiitaのアドベントカレンダーに参加したので最近チャレンジした認証機能`devise`についての学びを記事にしたいと思います。

https://qiita.com/advent-calendar/2024/engineering-careers-1


## 環境
Windows, WSL
Docker
Ruby 3.2.3
Rails 7.1.3
※deviseはすでに導入済みなので、導入手順については割愛させていただきます。一応👇下記記事を参考に導入したのでおいておきます。

https://zenn.dev/code_journey_ys/articles/7ca7e8f1933dc3

https://qiita.com/Hal_mai/items/350c400e8763ce0487a3

## 

まずは`config/application.rb `に設定を記述していきます
```
config.i18n.default_locale = :ja
```

そしてi18nによる日本語化対応でGemfileに以下を追加
```
gem 'rails-i18n', '~> 7.0.0'
```

この後インストール等を行いました。
この段階でのバリデーションメッセージ表記はこんな感じ👇
[![Image from Gyazo](https://i.gyazo.com/095043b53670bd0ce2fd1f515a5653d0.png)](https://gyazo.com/095043b53670bd0ce2fd1f515a5653d0)

私はここで初めてdeviseを使用するとデフォルトで生成される`config/locales/devise.en.yml`と`config/locales/en.yml`というファイルの存在を知りました。


調べていくと下記gemが必要になるそうで早速インストール
```
gem 'devise-i18n'
```
👆Deviseの多言語対応を簡単にするためのGemになります。

https://github.com/tigrish/devise-i18n


ついでにインストールの時のコマンド等は下記を実行いました
```
$ docker compose run web bundle install
$ docker compose restart
$ docker compose exec web bin/dev
```

再度新規登録画面を確認すると、無事日本語に！！
[![Image from Gyazo](https://i.gyazo.com/b4b6e0a5880d868cc5e1112792fa2c7d.png)](https://gyazo.com/b4b6e0a5880d868cc5e1112792fa2c7d)


## 考察
- **`devise-i18n`のインストール**: これにより、Deviseの翻訳が含まれている多言語対応の機能が追加される。ただし、デフォルトでは英語（`en`）の翻訳が適用。
- **`config.i18n.default_locale = :ja`の設定**: この設定を行うことで、アプリケーション全体のデフォルトのロケールを日本語（`ja`）に変更。これにより、`devise-i18n`が提供する日本語の翻訳が適用。

https://qiita.com/shimadama/items/7e5c3d75c9a9f51abdd5


## さいごにまとめ  
今回の記事では、`Devise`を使った認証機能の日本語化について学んだ内容を共有しました。特に以下の点がポイントでした：  

- **`devise-i18n`を導入することで多言語対応が容易になること**  
- **`config.i18n.default_locale = :ja`を設定することで、日本語の翻訳が適用されること**  
- **Docker環境でのGemインストールや再起動手順の実践**  

実際に画面が日本語化されるのを確認できたときには、大きな達成感を得られました。また、デフォルトで生成される`devise.en.yml`や`en.yml`ファイルについて知ることができ、今後のカスタマイズの可能性も見えてきました。

これからも、認証機能のカスタマイズや、さらに便利な設定を学んでいきたいと思っています。今回の記事が、同じように`Devise`を使い始めた方や、多言語対応に挑戦している方の助けになれば幸いです。
ゲームクリエイター甲子園に提出した「Spell Craft」の制作裏話　Unity

# ゲームクリエイター甲子園

https://game.creators-guild.com/gck/#main

https://gameparade.creators-guild.com/works/2663

ゲームクリエイター甲子園の大賞にノミネートされてます。
結果発表は1月19日。
みんなのゲームパレードから投票してくれると嬉しい！（上のリンク）
サイト内応援ランキング期間:2024年12月16日（月）～2025年1月5日（日）

# Spell Craft PV
![サムネイル.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3955314/1ec2f9f1-46aa-44d0-4d1a-6ff7a7e89701.jpeg)
<iframe width="600" height="400" src="https://www.youtube.com/embed/Ekox02k_xkc?si=3CHW2dtTWHCjhpEl" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

# 制作裏話

### 初期案
私は家から15分ぐらいの高校に自転車で通学しているのですが、よくその間にアイデアを考えたりします。
このゲームの初期案は原子の構造を書き換えるパズル？ゲームのようなアイデアでした。
今は完全にファンタジーなので全然変わりましたね。魔法構築の要素はここから生まれました。

### 企画書
珍しいかもしれませんが企画書を書くのがめちゃくちゃ好きです。
作り始めてすらいないゲームの企画書が4枚ぐらいあります。それぞれ3枚づつぐらい。
思いついたアイデアはとりあえずメモします。使わなそうでも忘れないように念のため。
このゲームの企画書はこんな感じです！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3955314/03576d65-2a9d-7be7-4a45-125d6c80bfba.png)

#### 個人的に書くべきだと思う項目

* <strong>メインの企画設計</strong> バランスを考えたり余分な要素を省いたり
* <strong>メモ</strong> 思いついたこと全部メモしとけば忘れない
* <strong>武器、アイテムの性能すべてのデータ</strong>　データが消えた時の対策とかになる
* <strong>バグのリスト</strong> 見つけたバグのメモ

### 苦戦したところ
このゲームを作っているときに最も苦戦したことはデーターのコピーです。
持ち物のリストから配列をコピーするときの方法に苦戦しました。
コピーには二種類あって

| コピーの種類 | 性質 | 特徴 |
|:-:|:-:|:-:|
| Shallow copy  | 浅いコピー  | 元のオブジェクトに対する参照を挿入 |
|  Deep copy | 深いコピー  | 元のオブジェクトのコピーを挿入 |

これがどう違うのかというと

```c#:Shallow copy (シャローコピー)
  // コピー元配列
int[] startData = { 0, 1, 2 };

// 配列をシャローコピーする　→参照のコピーになる。
int[] copyData = startData;

//　コピー後のほうを変更する。
copyData[0] = 3;

//　結果を表示する。
Debug.Log("コピー前: " + startData[0] + " コピー後: " + copyData[0]);
```
```text:結果
コピー前: 3 コピー後: 3
```

コピー前のデータも変わってしまった！

```c#:Deep copy (ディープコピー)
// コピー元配列
int[] startData = { 0, 1, 2 };

// コピー元と同じ長さのコピー先配列を定義する（空の配列）
int[] copyData = new string[startData.Length];

// 配列をディープコピーする
Array.Copy(startData, copyData, startData.Length);

//　コピー後のほうを変更する。
copyData[0] = 3;

//　結果を表示する。
Debug.Log("コピー前: " + startData[0] + " コピー後: " + copyData[0]);
```
```text:結果
コピー前: 0 コピー後: 3
```

コピー前のデータを変えずにコピー後を変更できた！

コピーの違いを知らなかったのでかなり苦戦しました。
知っとくとかなり役に立つと思います！

## 個人的に完成度を上げるのに必要だと思うこと

### ポストエフェクト
カメラの最終出力の前に加工する！すごく大切！

* <strong>Bloom</strong> グロー、光源の輝きを変える。つけるとかなり雰囲気変わる！
* <strong>Color Adjustments</strong>　色調を変える。雰囲気を変えたいときに良い
* <strong>Vignette</strong>　画面淵に色をつける。黒色を絶妙に入れるといい感じになります

### UI
UIは見やすい＆世界観に合うことが大切。

1. なるべく文字数を減らす
1. 情報の優先順位を考えて配置、サイズを考える
1. 似たジャンルの有名ゲームを参考にして作るといい感じになる

## まとめ
以上のようなことを考えてこのゲームを作っていました！
ゲームクリエイター甲子園の展示会＆結果発表は1ヶ月後です。
もしよかったら見に来てみてくださいね。

最後に

応援ボタン＆投票お願いします！

https://gameparade.creators-guild.com/works/2663
プロダクトマネージャーとプロジェクトマネージャーを兼任した時の苦労や是非 

## はじめに
現在、私はあるパッケージシステムのプロダクトマネージャーを担当しています。当初は、開発エンジニアから始まり、製品開発のプロジェクトマネージャーを経て、現職に就いています。
一時期、「プロダクトマネージャー」と「プロジェクトマネージャー」の両方を兼任したことがありました。その時の苦労や兼任の是非について触れたいと思います。

## 概要
この記事では、以下に触れます。
- プロダクトマネージャーとプロジェクトマネージャーの違い
- 兼任する際のメリット/デメリット
- 兼任の是非

## 「プロダクトマネージャー」とは
プロダクトマネージャーは、製品やサービスの開発および提供を統括する人です。マーケット調査、ビジネス戦略の策定、製品・サービスの企画、ビジョン・ロードマップの提供、開発からリリースまでプロダクトのライフサイクル全体を管理します。そのプロダクトを用いたビジネスの成功に責任を持つと考えられます。

※後述のプロジェクトマネージャーを区別して「PdM」と表記します。

## 「プロジェクトマネージャー」とは
プロジェクトマネージャーは、プロジェクトの計画、実行、推進、調整に関連する業務を管理する人です。目標設定、スケジュール管理、リソースの割当などを担当します。製品開発プロジェクトにおいては、QCD（Q:品質、C:コスト、D:納期）に責任を持つと考えられます。

※前述のプロダクトマネージャーを区別して「PjM」と表記します。

## それぞれの違い
PdMとPjMには、簡単にいうと以下の違いがあります。
- PdMは「何を作るか」「何のために作るか」を考える人
- PjMは「どうやって作るか」「いつまでに作るか」を考える人

## 兼任するメリット
兼任することには、以下のようなメリットがあると考えられます。

- **人員不足への対処**
専任を置くのが難しい組織であっても、リソースを共有できる。
- **一貫した製品の方向性**
PjMが製品のビジョンを持つことで、プロジェクトの目標や方向性が一貫して保たれる。
- **コミュニケーションロスの低減**
コミュニケーションによる情報漏れや認識のずれを最小限に抑えられる。

## 兼任するデメリット
逆に兼任することには、以下のようなデメリットがあると考えられます。

- **スキル不足と負荷の増加**
広範囲の役割が求められるため、十分なスキルが必要となり、役割をこなすためには負荷も増加する。
- **タスクの優先順位付け**
役割や責任の範囲が異なるため、優先すべき事項の判断が難しい。一方の役割、成果を優先してしまう。
- **ステークホルダーとの調整**
必ずしも利害が一致しない、多くのステークホルダーと調整が必要となり、調整が困難となる。

## 兼任の是非
製品・サービスの規模や個人の能力にもよりますが、可能であれば兼任は避けた方が望ましいと考えます。

## 兼任の事例
新規や小規模の製品やサービスの開発では、それほど多くの人員を割けるわけではないため、PdMとPjMでそれぞれ別の人を立てるのは難しいでしょう。
実際、私の現場でも、「製品開発のPMをやって」と言われて、PdMとPjMを区別することなく、両方の役割を期待されていました:sweat_smile:

「こんな製品にしたいよね」という想いはあるものの、実際の製品開発プロジェクトの場面になると、期間やリソースの関係上、「まずは製品を作って納期どおりにリリースすることだ」とPjMの視点を優先しがちになってしまいました。その結果、製品は無事にリリースできたけれども、「ユーザーにとって何に役立つのか？」「なぜ、この機能は優先的に作ったのか？」となってしまったことも・・・。

PdMとしての役割の認識やスキルが不足していた部分も多々ありますが、時間的な制約もある中で成果を出そうとすると、目先のことを優先しがちというのは、人間の性なのかもしれません。

## おわりに
理屈では、PdMとPjMの兼任は避けたほうがよい、ということは同意できる話かと思います。それでも、限られた人員リソースや個々の事情により、兼任を避けられないことは多々あるかと思います。PdMとPjMを兼任したとしても、適切に役割を演じ切ることができれば、兼任のメリットを活かしつつ、良い製品やサービスを作っていけることでしょう。

一方、PdMとPjMにそれぞれ専任を置けるのであれば、役割や責任の範囲が明確になり、より幅広い視点で考えられることになります。単に製品やサービスを作るだけではなく、それをビジネスに繋げなくては意味がありません。特に新規の製品やサービスの開発の場面では、PdMに未来を描く時間を与えてあげてください（私にください:grinning:）。

- **PdM：世の中が求めるものを、大きく描く**
- **PjM：限られた期間とリソースで、それを実現する**

両者の役割がうまくかみ合ったときにこそ、よい製品やサービスが生まれるのではないでしょうか。
クラウドサービスと仮想化技術の関係

カリキュラム内で、READMEの使用環境のOS部分をLinux指定されました。
私はWindowsのパソコンを使用していたため、なぜかと思い、調べたことをまとめます。

---

### なぜLinuxだったのか
**＝cloud9を使用していたため。**

**cloud9**とは：
AWSが提供するクラウド上の統合開発環境。
ブラウザ上で編集・実行・デバックができるため、ローカルマシンに開発環境作る必要がない。

cloud9はAWSのクラウドサーバ上で動作しており、そのサーバはLinuxベースの仮想環境で構成される。

---

### なぜcloud9だと、OSがLinuxになるの？
AWSが仮想環境上にLinuxを配置してサービス（この場合はcloud9）を提供しているから。
仮想環境にすることで、１台の物理サーバ上で複数のLinux環境（仮想マシン・コンテナ）を同時に稼働できる。

![仮想環境.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3905096/3d9c9cd9-7982-668e-7804-092935b67965.jpeg)

---

### 今回調べた用語

### 1. コンテナ：
アプリケーションとその実行に必要な依存関係（ライブラリ、設定ファイル、バイナリなど）を1つにまとめた、ホストOS上で動作できる軽量な仮想環境。

**コンテナ化の代表的なツール＝`Docker`**

**コンテナのメリット**
依存環境一括管理、どの環境でも動く、軽量で高速　　など

---

### 2. 仮想化技術
物理的なハードウェアをソフトウェアで分割（＝論理的に分割）して、
複数の仮想環境を作ること。
例えば、1台の物理サーバーの中に、複数の仮想サーバーを作成し、
私のサーバとして、知人のサーバのして…という形でそれぞれ独立して動作させる。

**クラウドサービスと仮想化技術の関係**  
クラウドサービスは、仮想化技術を利用することで下記を実現している

1. **1台の物理サーバーを効率的に使う**  
   - 仮想化を使うことで、1台の物理サーバーを複数のユーザーや用途に分割して提供できる。  

2. **柔軟なリソース管理**  
   - 仮想マシンやコンテナを動的に増減できるため、必要に応じてCPUやメモリ、ストレージの割り当てを変更できる。  

3. **コスト削減**  
   - 仮想化によってハードウェアの利用効率が上がり、物理サーバーの台数を増やさなくてもリソースを有効活用できる。  
   - 利用者は自分でサーバーを購入・管理する必要がなく、クラウドサービスを利用することで必要な分だけ料金を支払えばいい。

4. **OSやソフトウェアの独立性**  
   - 仮想化により、1つの物理サーバー上で異なるOS（Linux、Windowsなど）を動かすことができる。  
   - 例えば、AWS EC2の仮想サーバーでLinux環境とWindows環境を同時に動かすことが可能。

**クラウドサービスに使われる仮想化の技術例**
1. **仮想マシン（VM）**  
   - 物理サーバー上にソフトウェア的に複数の「仮想サーバー」を構築。  
   - 例: **VMware**、**Hyper-V**、**KVM** など。

2. **コンテナ技術**  
   - 仮想マシンよりも軽量な「コンテナ」を使い、アプリケーション単位で環境を仮想化する。  
   - 例: **Docker**、**Kubernetes**。

3. **仮想デスクトップ**  
   - 仮想化技術を使って、クラウド上に「デスクトップ環境」を提供。  
   - 例: **Amazon WorkSpaces**、**Microsoft Azure Virtual Desktop**。

---

### 3. クラウドサービス：
**仮想化技術を利用して**、インターネット経由で
ソフトウェア、データ、リソース（サーバー、ストレージ、ネットワークなど）を
必要なときに必要な分だけ提供するサービス。

利用者は、物理的なハードウェアやインフラを自前で用意する必要がなくなる。
**＝経費が浮く！スペースが空く！**

**クラウドサービスの種類**  

| **分類**                  | **概要**                                             | **例**                                  |
|---------------------------|----------------------------------------------------|---------------------------------------|
| **IaaS** (Infrastructure as a Service) | 仮想サーバーやストレージなど、インフラを提供              | レンタルサーバー(さくらのレンタルサーバー) |
| **PaaS** (Platform as a Service)       | 開発プラットフォームを提供し、アプリ開発を効率化          | AWS Cloud9         |
| **SaaS** (Software as a Service)       | ソフトウェアやアプリケーションそのものを提供              | Gmail, Dropbox, Google Drive         |
僕のキーボード購入の決め手

## キーボードを買い替えたい
キーボードの使い心地があまりよくなかったため、新しいキーボードを購入しました。
新しいキーボードの購入にあたって、まずは「欲しいキーボードの条件」をハッキリさせるために「キーボードの不満」を洗い出してみます。

## キーボードの不満
* テンキーが邪魔
* コードが邪魔
* USBポートを使う
* 押し心地が微妙
* 日本語の印字がダサい
* 光らない

以上の不満から、欲しいキーボードの条件は以下になりました。

## 欲しいキーボードの条件
* テンキーレス
* Bluetooth対応
* 良い押し心地（実際に触って確かめる）
* 日本語の印字がないキートップ
* 光る

上記に加えて、以下の条件も追加しました。

* 完成品（組み立てはハードルが高い）
* 日本語配列

## キーボード探し
実際に触って決めたかったので、こちらのお店に向かいました。

https://tenpo.tsukumo.co.jp/stores/view/honten

## 購入決定
様々なキーボードを触って確かめた結果、欲しいキーボードの条件をすべてクリアした激アツキーボードを発見しました！

https://www.razer.com/jp-jp/gaming-keyboards/razer-deathstalker-v2-pro-tenkeyless?srsltid=AfmBOora42EOuWOc0m-1e-JSF7MxboJyGxFHV05MEKTvjddzjy13zZTI

## 最後に
キーボード購入を検討されているみなさんも、ぜひ「理想のキーボード」を思い浮かべてみてください。
Databricksクラスターでグループ専用モードを利用できるようになりました！

これは嬉しい。こちらのアップデートです。

https://docs.databricks.com/ja/release-notes/product/2024/december.html#assign-compute-resources-to-groups-public-preview

**グループに計算リソースを割り当て (パブリック プレビュー)**
> 新しい 専用 アクセスモード (以前の シングル ユーザー) により、汎用コンピュートをユーザー グループまたは単一のユーザーに割り当てることができます。詳しくは、[ユーザー グループにコンピュート リソースを割り当てる](https://docs.databricks.com/ja/compute/group-access.html) を参照してください。

# なぜ嬉しいのか

これまでは、Databricks(汎用/ジョブ)クラスターでは以下のアクセスモードが提供されていました。

![Screenshot 2024-12-18 at 11.23.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/dea9bf32-7947-3102-4dad-43ce457fff4c.png)

複数ユーザーでクラスターを共有する場合は**共有**一択だったのですが、機械学習ランタイムが使えないなど、[こちら](https://docs.databricks.com/ja/compute/access-mode-limitations.html#shared-access-mode-limitations-on-unity-catalog)にあるような制限がありました。なので、Databricksのフル機能を使おうとすると**シングルユーザー**モードを使うのですが、名前の通り一人のユーザーしか使えないモードなのです。痛し痒しです。

それが、今回導入される新たな **専用(Dedicated)** アクセスモードによって、**シングルユーザーモードのクラスターの機能を複数ユーザーで活用**できるようになります。かつてのシングルユーザーアクセスモードが拡張され、グループも割り当てられるようになって**専用**アクセスモードになったという流れです。

なお、共有アクセスモードは標準(Standard)アクセスモードに名称変更されています。

マニュアルはこちら(翻訳は修正中なので明日には直っているはずです)。

https://docs.databricks.com/ja/compute/group-access.html

# ウォークスルー

## 機能の有効化

ワークスペース管理者がメニューの**プレビュー**にアクセスします。

![Screenshot 2024-12-18 at 11.16.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/6134930a-9219-c601-b9aa-c5c0cc561659.png)

**Compute: Dedicated group clusters**がありますので、こちらをオンにします。画面をリロードします。

## クラスターの作成

クラスター作成画面が[シンプルフォーム](https://docs.databricks.com/ja/compute/simple-form.html)にリニューアルされています。前の画面に戻すには上にある**シンプルなフォーム**をオフにします。表示される項目自体は変わっていません。個人的には最初に**機械学習**を選べるようになったのが嬉しいです。結構ありがちなのは`MLランタイムを選ぶのを忘れる`でしたので。あと、デフォルトはマルチノードですが、**シングルノード**をチェックすることで、シングルノードクラスターに切り替えることができます。

![Screenshot 2024-12-18 at 11.18.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/f8868ed2-894c-b307-f76e-20daf7e64472.png)

基本設定はこんな感じで。

![Screenshot 2024-12-18 at 11.18.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/1d4e8fff-098f-256a-a263-bbc0caf7219c.png)

画面を下にスクロールして**Advanced**を展開します。ここでアクセスモードを指定します。デフォルトではコンピュート構成に基づいて**自動**でアクセスモードが決定されています。今回は専用のままで問題ないので、作成済みのグループ`DS`を選択します。

![Screenshot 2024-12-18 at 11.36.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/36cb8781-f6fe-c992-f212-47678f26dd30.png)

![Screenshot 2024-12-18 at 11.20.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/5111caf4-add5-1742-5b3d-6594738f8ca1.png)

これで、グループメンバーがアクセスできて、かつてのシングルユーザークラスターで利用できたフル機能を活用できるようになります！[制限事項](https://docs.databricks.com/ja/compute/group-access.html#limitations)にご留意の上ご活用ください！


### はじめてのDatabricks

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

### Databricks無料トライアル

[Databricks無料トライアル](https://databricks.com/jp/try-databricks)
自PCにインストールされている証明書をテキスト（ｃｓｖ）出力する仕組み

### やりたいこと

PC 交換時に交換前の PC に入っている証明書を把握しておきたい。

### やり方
「個人」の証明書を表示させたい場合は下記のコマンドを実行します。

```サンプル.ps1
Get-ChildItem -Path Cert:\CurrentUser\My
```

全ての証明書を網羅し、テキスト（ｃｓｖ）出力する場合は下記の PowerShell を実行します。

```証明書出力.ps1
# 検索する証明書ストアのリスト
$stores = @()
$stores += "My"
$stores += "Root"
$stores += "CA"
$stores += "TrustedPeople"
$stores += "TrustedPublisher"
$stores += "AuthRoot"
$stores += "Disallowed"
$stores += "ClientAuthIssuer"
$stores += "UserDS"
$stores += "ACRS"
$stores += "REQUEST"
$stores += "addressbook"
$stores += "Local NonRemovable Certificates"
$stores += "SmartCardRoot"
$stores += "Trust"

# 全ての証明書を格納するリスト
$allCerts = @()

# 各ストアから証明書を取得
foreach ($store in $stores) {
    $localMachineCerts = Get-ChildItem -Path "Cert:\LocalMachine\$store" | Select-Object -Property *, @{Name="Store";Expression={"LocalMachine\$store"}}
    $currentUserCerts = Get-ChildItem -Path "Cert:\CurrentUser\$store" | Select-Object -Property *, @{Name="Store";Expression={"CurrentUser\$store"}}
    $allCerts += $localMachineCerts
    $allCerts += $currentUserCerts
}

# 指定された情報に一致する証明書を検索
$matchingCerts = $allCerts

# 結果を表示
if ($matchingCerts) {
    $matchingCerts | Select-Object -Property Store, PSPath, Subject, Issuer, Thumbprint, NotBefore, NotAfter | `
        Export-Csv -Path "$ENV:USERPROFILE\Desktop\$($ENV:USERNAME)_$($ENV:COMPUTERNAME)_証明書_$(Get-Date -Format yyyyMMdd).csv" -NoTypeInformation -Encoding Default
} else {
    Write-Output "指定された情報に一致する証明書は見つかりませんでした。"
}
```

:::note warn
注意
検索機能を拡張するための処理が入っています。
実装しておりませんので無意味な処理です。
※「\\$matchingCerts = $allCerts」の部分。
:::

### 実行結果

デスクトップ上に「ユーザー名_ホスト名_証明書_yyyyMMdd.csv」が出力されます。

### 検索用
証明書
証明書ストア
個人
ほかの人
中間証明機関
信頼されたルート証明機関
頼された発行元
頼されない発行元
発行先
発行者
有効期限
フレンドリ名
サーバー認証
クライアント認証
コード署名
電子メールの保護
tcpdumpとその他のパケットキャプチャツールの比較

# tcpdump
ネットワ－クインターフェースを流れるパケットの詳細(プロトコル，送信元/宛先IPアドレス，ポート番号)などを表示します．

インストール・実行
```
$ sudo apt install tcpdump
$ sudo tcpdump
```
```$ sudo tcpdump```の実行結果
```
21:11:40.083252 ARP, Request who-has 192.168.100.96 tell 192.168.100.99, length 46
21:11:40.182684 IP vm03.ssh > 192.168.100.37.14024: Flags [P.], seq 5128:5612, ack 1, win 611, options [nop,nop,TS val 3341984239 ecr 4070164734], length 484
21:11:40.182846 IP vm03.54844 > 192.168.100.35.domain: 11108+ [1au] PTR? 99.100.168.192.in-addr.arpa. (56)
```
### tcpdumpとその他ツールの比較
| ツール | tcpdumpと異なる機能 |
|:-:|:-:|
| iftop | 各ソケットの送受信データ量をバーで表示 |
| tshark | キャプチャデータをpcap形式で出力することができ，WireSharkで読込可能 |
| bmon | 各NICのトラフィックをグラフ形式で表示 |
| iptraf | ホスト間の通信をGUIに近い形で操作ができる |
| nload | 各NICのトラフィックを-iまたは-oでメモリ指定することでグラフで表示 |
| nethogs | 各プロセスIDのネットワークトラフィックを表示 |
| VnStat | daemon起動でトラフィック量を記録し，レポート出力が可能 |

# iftop
ソケットごとの通信状況に加え，送受信データ量を視覚的に表示します．

インストール・実行
```
$ sudo apt-get install iftop
$ sudo iftop
```
```$ sudo iftop```の実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3845343/3f9fd50e-6352-7203-e20f-03d36c667466.png)







# tshark
WiresharkのCLI版である。
```sudo tshark -w 'ファイル名.pcap'```でキャプチャ内容をpcap形式で保存することで，そのファイルをWireshark上でGUI上で表示することが可能

インストール・実行
```
$ sudo apt install tshark
$ sudo tshark
```
```$ sudo tshark```の実行例
```
Capturing on 'ens34'
    1 0.000000000 Espressif_d0:41:94 → Broadcast    ARP 60 ARP Announcement for 192.168.100.49
    2 0.023612243 VMware_19:a4:b3 → Broadcast    ARP 60 Who has 192.168.100.96? Tell 192.168.100.99
    3 0.394024560 Espressif_dc:a7:64 → Broadcast    ARP 60 ARP Announcement for 192.168.100.54
    4 0.440639125 TpLinkTechno_49:34:95 → Broadcast    Realtek 60
    5 0.477748707 192.168.100.207 → 192.168.100.37 SSH 302 Server: Encrypted packet (len=236)
    6 0.477999945 192.168.100.37 → 192.168.100.207 TCP 66 12184 → 22 [ACK] Seq=1 Ack=237 Win=1055 Len=0 TSval=4071832265 TSecr=3343651673
```



# bmon
各ネットワークインターフェースの送信データ量の利用状況と，そのグラフを表示します．

インストール・実行
```
$ sudo apt install bmon
$ bmon
```
```$ bmon```の実行例

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3845343/9d2a2cc6-c3b3-b307-3772-0e8cedf57a24.png)




# iptraf
IPアドレスごとのトラフィック統計や，インターフェースの統計を表示します．

インストール・実行
```
$ sudo apt install iptraf-ng
$ sudo iptraf
```
```$ sudo iptraf```の実行例

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3845343/6f43a332-3ba9-4a50-a605-2f3140e3079a.png)

IP traffic monitorを選択した際の画面

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3845343/a136110a-8548-3ae5-24e9-81d8607d473a.png)







# nload
ネットワークの受信(Incoming)・送信(Outgoing)データ量を表示します．
インストール・実行

```
$ sudo apt install nload
$ nload
```
```$ sudo nload```の実行例

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3845343/674c4cac-ee87-bf76-01fa-709d9acfa711.png)





# nethogs
プロセスごとの帯域幅使用量を表示します．

インストール・実行
```
$ sudo apt install nethogs
$ sudo nethogs
```
```$ sudo nethogs```の実行結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3845343/4d6db739-93fa-4630-7015-ab32568fd390.png)
RHEL 9やRocky Linux 9で古いsshdサーバに接続できない場合の対処方法

## RHEL 9やRocky Linux 9で古いsshdサーバに接続できない場合の対処方法

RHEL 9やRocky Linux 9では、セキュリティ強化のため、古い暗号化方式や認証方法が無効化されています。そのため、古いsshdサーバに接続しようとするとエラーが出る場合があります。例えば、次のようなエラーです：

```
Unable to negotiate with [host] port 22: no matching host key type found. Their offer: ssh-rsa,ssh-dss
```

また、次のエラーが出ることもあります。

```
ssh_dispatch_run_fatal: Connection to 192.168.1.195 port 22: error in libcrypto
```

これらのエラーが発生する原因と、その対処方法を以下に説明します。

---

## エラーの原因

エラーは以下の2つに分けて考えることができます。

### サーバ側の原因

- **古い鍵交換方式 (`ssh-rsa`, `ssh-dss`) の使用**: 古いsshdサーバでは、これらのアルゴリズムが使われていることがあります。このため、`Unable to negotiate with [host]...` のエラーが発生します。
- **古い暗号化アルゴリズム (`aes128-cbc`, `3des-cbc`) の使用**: セキュリティの観点から非推奨になっているため、接続が拒否されます。

### クライアント側 (RHEL 9やRocky Linux 9) の原因

- **鍵交換方式や暗号化方式が無効化されている**: クライアント側でこれらがデフォルト無効化されているため、サーバに接続できず、`error in libcrypto` のエラーが出ます。
- **FIPSモードの有効化**: FIPSモードでは特定のアルゴリズムしか許可されないため、接続が制限されます。

---

## 対処方法

### 1. サーバを変更できる場合

サーバ側で設定を変更するのが最善の方法です。具体的には、以下のように設定を変更します。

- OpenSSHのバージョンをアップデートする。
- サーバ側の設定ファイル `sshd_config` に必要なアルゴリズムを追加する。

以下の例を参考にしてください：

```ssh-config
HostKeyAlgorithms ssh-rsa,ssh-dss
KexAlgorithms diffie-hellman-group1-sha1,diffie-hellman-group14-sha1
Ciphers aes128-cbc,3des-cbc
```

設定を変更した後、`sshd`を再起動します：

```bash
sudo systemctl restart sshd
```

### 2. クライアント側で対応する場合

サーバを変更できない場合、クライアント側の設定を調整します。

#### 2-1. 設定ファイルで有効化

SSHの設定ファイル (`~/.ssh/config` または `/etc/ssh/ssh_config`) に以下を追加します。

```ssh-config
Host [対象サーバのホスト名またはIPアドレス]
    HostKeyAlgorithms +ssh-rsa
    PubkeyAcceptedKeyTypes +ssh-rsa
    KexAlgorithms +diffie-hellman-group1-sha1,diffie-hellman-group14-sha1
```

- `HostKeyAlgorithms` : サーバが使うホスト鍵のアルゴリズムを追加します。
- `PubkeyAcceptedKeyTypes` : クライアント側で許可する公開鍵アルゴリズムを指定します。
- `KexAlgorithms` : 古い鍵交換アルゴリズムを追加します。

#### 2-2. コマンドで一時的に対応

設定ファイルを変更したくない場合、SSHコマンドにオプションを指定して接続します。

```bash
ssh -o HostKeyAlgorithms=+ssh-rsa -o PubkeyAcceptedKeyTypes=+ssh-rsa \
    -o KexAlgorithms=+diffie-hellman-group1-sha1,diffie-hellman-group14-sha1 [ユーザー名]@[対象サーバ]
```

#### 2-3. 暗号化方式を追加

暗号化方式が原因で接続できない場合、以下の設定を追加します：

```ssh-config
Host [対象サーバのホスト名またはIPアドレス]
    Ciphers +aes128-cbc,3des-cbc
```

#### 2-4. ポリシーを変更する

RHEL 9では、暗号化ポリシーを一時的に変更するコマンドを利用できます。以下のコマンドを実行すると、SHA-1を含む古いアルゴリズムが有効になります：

```bash
sudo update-crypto-policies --set DEFAULT:SHA1
```

この設定を変更すると、古い暗号化方式も使用可能になります。ただし、セキュリティリスクが高まるため、一時的な利用にとどめ、不要になったらデフォルトに戻すことを推奨します。

元に戻すには以下を実行します：

```bash
sudo update-crypto-policies --set DEFAULT
```

#### 2-5. FIPSモードを確認

FIPSモードが有効になっている場合、以下のコマンドで確認できます：

```bash
cat /proc/sys/crypto/fips_enabled
```

- `1` : 有効
- `0` : 無効

FIPSモードが有効な場合、必要に応じて無効化し、再起動が必要です。

---

## 注意点

古い暗号化方式や鍵交換方式を有効化すると、セキュリティリスクが高まります。可能であれば、サーバ側の更新を検討してください。また、設定を変更する際は、影響を最小限にするため、特定のホストにのみ適用するようにしましょう。

---

## まとめ

RHEL 9やRocky Linux 9で古いsshdサーバに接続するには、以下の方法で対応可能です。

1. サーバまたはクライアント側の設定を変更して古いアルゴリズムを有効化する。
2. 必要に応じてFIPSモードを無効化する。

ただし、セキュリティ上の理由から、可能な限りサーバのアップデートを推奨します。
Gitメモ: ブランチ削除

```
// ローカルブランチを削除
git branch -d localBranchName

// リモートブランチを削除
git push origin --delete remoteBranchName

// 複数ローカルブランチ削除(Windows PowerShell)
git branch -d (git branch --list '3.2.*').trim()

// 複数ローカルブランチ削除(その他)
git branch -d `git branch --list '3.2.*'`
```
ポート番号

ポート番号は0〜65535の範囲で定義されている。
また以下の3つに分類される。

**①ウェルノウンポート**
範囲：0〜1023
標準的なサービスやプロトコルに割り当てられる

**②登録済ポート**
範囲：1024〜49151
特定のアプリケーションやソフトウェアベンダーが登録して使用するポート番号
（例）SQLやオラクル

**③動的/プライベートボート**
範囲：49152〜65535
一時的な通信（エフェメラルポート）やユーザーが自由に使用できるポート
（例）クライアント側アプリケーションがサーバーに接続する際に動的に割り当てられるポート


|ポート番号 | プロトコル | 用途 |
|:--------|:--------|:--------|
|20, 21	| FTP |ファイル転送 |
|22 |SSH |セキュアなリモート接続 |
|23 |Telnet |リモート接続（非セキュア）|
|25 |SMTP |メール送信 |
|53 |DNS |名前解決 |
|67, 68 | DHCP | IPアドレスの自動割り当て |
|80 | HTTP	| Web通信（非暗号化） |
|110 | POP3 | メール受信 |
|119 | NNTP	 | ネットニュース転送 |
|123 | NTP | 時刻同期 |
|143 | IMAP | メール受信（サーバー同期型）　|
|161, 162 | SNMP | ネットワーク管理 |
|443 | HTTPS | Web通信（暗号化）|
|993 | IMAP over SSL | セキュアなメール受信 |
|995 | POP3 over SSL | セキュアなメール受信 |
|1433 | Microsoft SQL | データベース接続（SQL Server）|
|3306 | MySQL | データベース接続（MySQL）　|
|3389 | RDP | リモートデスクトップ　|

## ポート番号の使い方
クライアントとサーバー間の通信ではサーバー側が「固定ポート番号」（ウェルノウンポートや登録済みポート）を使用しクライアント側は動的にポート番号を割り当てている

（例）
クライアントがWebサイトにアクセスする際、サーバーはHTTPの80番ポートまたはHTTPSの443番ポートで待機。
クライアント側は動的に49152以上のポート番号が割り当てられる

またポート番号主にトランスポート層で使用されるが一部アプリケーション層やネットワーク層でも使われる


## ポート番号のセキュリティ
①不要なポートは閉じる
攻撃者が空いているポートを悪用する可能性がある
②ファイアウォールの設定
重要なポート（80、443、22など）以外のポートへのアクセス制限
③ポートスキャン対策
攻撃者によるポートスキャンを検出し切断する仕組みを導入

:::note warn
ポート番号は通信の管理や識別を行うための重要な要素。
システム管理やネットワーク構築ではポート番号の役割や設定が欠かせない
:::
AWS SAA 受験に向けたメモ

個人的に何度も忘れてしまうものや分かりにくいものをまとめていきます！
試験範囲を網羅しているわけではないのでご注意を！

https://qiita.com/hoshi_/items/c5865afd087383c5e649

https://qiita.com/hoshi_/items/733ef348ff9d55018fc8

https://qiita.com/hoshi_/items/dd0073c9000a8c230a93

https://qiita.com/hoshi_/items/e165928c8c3162f9a69e

https://qiita.com/hoshi_/items/10c9a96d5a547c5ca8bb

https://qiita.com/hoshi_/items/2fa61b30d74a40bc5420

https://qiita.com/hoshi_/items/72892916f57cfbc38b9a
介護開発から介護QAへ転職した話

:::note info
この記事は[LITALICO Engineers Advent Calendar 2024](https://qiita.com/advent-calendar/2024/litalico) の23日目の記事です。
:::


# 初めに
初めまして。2022年12月にLITALICOへ中途入社したQAエンジニアの@kamyohです。
本記事は私が介護請求ソフトの開発からQAへ転職した感想を記載したものです。

# 記事の見出し
* 前の職場について
* 担当プロダクト
* 転職した際の変化
* 入社してから現在までのお仕事
* 転職して得られたもの
* おわりに

# 前の職場について
前の職場は医療・介護請求ソフトの開発会社です。
私は介護請求ソフトの開発チームに所属しており、約10年間介護ソフトの開発に携わっていました。
ちょうど新しい介護請求ソフトの開発が開始したタイミングだったので、マスタ～請求までの一通りのソフト開発に携わりました。

# 担当プロダクト
「ナーシングネットプラスワン」という介護ソフトのQAを担当しています。
「ナーシングネットプラスワン」は介護保険請求を主軸としつつ、医療訪問看護、障害福祉サービスなどの幅広いサービスに対応しています。

# 転職した際の変化
**ソフトの変化**
前職の介護ソフトと違いはあれど、あくまで同じ介護保険制度を元に作られているソフトということで大きなつまづきはなく、スムーズに順応できました。

**用語の変化**
予想外に困った部分でした。
・前の職場で当然のように使っていた単語が実はローカルなものだった。
・同じ単語でも指しているものが違った。
・略称が違った。
上記が要因で会話が微妙にズレることがありました。
そのことに気づいてからは、何の言葉が通じていて、何の言葉が通じていないかを意識しながら会話することを心掛けました。

**業務の変化（開発からQAへ）**
仕様設計やプログラミングから、品質保証の業務へと変わりました。
そもそも品質とは何か？品質を上げるためには何をすれば良いのか？など基礎から学び直しが必要でした。
今までの開発者として視点がむしろ邪魔になるようなこともあり、一度、頭を空にして学ぶ必要がありました。

# 入社してから現在までのお仕事
**品質分析**
毎月のリリースチケットに対し、ユーザーストーリーの作成からリスクの洗い出しを行います。
ここでリスクを早期に発見して共有することで実装の修正コストを最小限に抑えたり、デグレでの品質低下を防ぐことができます。
前職では意識してやってこなかった部分なので、始めのうちはなかなか上手く行かず苦戦していました。（今は上手くやっているつもり。）

**テスト**
テスト設計～テスト実施までを行います。
前職では仕様書やコードを見ながらのホワイトボックステストでしたが、QAとなったことでブラックボックステストに変わりました。
慣れるまではテストの観点漏れ等を指摘されることが多かったです。

**法改正（介護）**
前職の経験を一番活かせた部分です。
法改正の前には介護保険制度に関する資料の作成や勉強会を開催し、法改正が始まってからは厚労省から公開される資料をまとめ、必要な対応の洗い出し、テスト設計～テスト実施まで行いました。


**法改正（障害福祉）**
障害福祉の法改正を初めて経験しました。
介護保険の法改正が終わった直後で期間が1月程度しかなかったのですが、LITALICOの他の障害福祉ソフトチームがまとめた資料を使用させて頂くことで無事にテスト設計を行うことができました。
また、テスト設計の過程でなぜその法改正を行うに至ったかについても調べることで障害福祉についての理解を深めることができました。

**法改正（医療訪問看護）**
医療訪問看護については前職で少し関わった程度なので介護程の知識は持っていない状態でした。
更には電子化という新しい仕組みが始まる改正内容でしたが、幸いにも施行月が4月ではなく6月にズレたため、改正資料をしっかりと確認し、開発の方と認識合わせしながら進めることで無事に対応することができました。

# 転職して得られたもの
**障害福祉のドメイン知識**
LITALICOへ転職する際に得たいと思っていた部分でした。
まだまだ未熟な部分もありますが、次の法改正時には自分で調べて対応を洗い出せるのではないかと思えるくらいには成長できました。
（やっぱりドメイン知識を習得するためには法改正を経験するのが一番だな。）

**医療訪問看護のドメイン知識**
こちらは転職時の期待値としては無かったのですが、得られて良かったです。
前職でも法改正時にテストを担当するくらいの経験はあったのですが、改正資料を読み解く経験はほとんど無かったため、今回の法改正を通して成長することができました。

**QAとして必要なスキル**
現在進行形ですが、ユーザーストーリーの作成、リスクの洗い出し、品質の向上をさせるための仕組みの作り方などを学んでいます。

# おわりに
介護ソフト開発から介護ソフトQAというドメイン知識を活かせる分野への転職だったので、活かせる経験があった分、馴染むのは早かった方なのかなという所感。
転職時に得たいと思っていた介護保険以外の法制度の知識も順調に学べているので、今後も頑張っていきたい。
【忘却録】MacOSをバージョンアップしたらVMが起動しなくなった件

## 概要
MacOSをバージョンアップしたら、VM環境の起動ができなくなり焦ったため、その時とった対応方法をまとめる。

### 環境情報
- OS：macOS Sonoma(14.7.1)
- VirtualBox：Version 7.0.8 r156879 (Qt5.15.2)

## 事の発端
macOS Venturaから macOS Sonomaにバージョンアップ後のこと。
久しぶりにVirtualBoxの開発環境を利用しようと「起動」ボタンを押すも、下記エラーとなりすぐ終了してしまう。

```ruby:エラー抜粋
The virtual machine 'VM名称' has terminated unexpectedly during startup because of signal 9.

```

PCを再起動してみるも、状況変わらず。


## 原因
- VirtualBox(7.0.8)側にて、コード署名がされていない状態で、正常に起動できていなかった

## 解決方法
１．ターミナルより下記コマンドを実行。
```ruby:コマンド
$ sudo codesign --force --deep --sign - /Applications/VirtualBox.app/Contents/Resources/VirtualBoxVM.app
```
２．VirtualBoxのマネージャー画面より、VM起動

３．エラー解消！




### 参考にさせていただいた記事
https://forums.virtualbox.org/viewtopic.php?t=108217

https://www.krombusch.de/?p=1272
c#で、なでしこ その15

# 概要
c#で、なでしこ、やってみた。
c#な、なでしこ、見つけたので、msbuildでコンパイルしてみた。
練習問題やってみた。

# 練習問題
ハノイの塔を解け。

# 参考にしたページ

https://qiita.com/kujirahand/items/d1fd5b8a6a702c82b66d


# サンプルコード

```

●円盤移動(SRCからDESへ)
　「{SRC}から{DES}へ移動」と表示


●ハノイ(円盤数をSRCからDESへTMPで)
　もし、円盤数=1ならば
　　SRCからDESへ円盤移動
　もし、円盤数が2以上ならば
　　(円盤数-1)をSRCからTMPへDESでハノイ
　　SRCからDESへ円盤移動
　　(円盤数-1)をTMPからDESへSRCでハノイ


3を「A」から「C」へ「B」でハノイ


```

# 実行結果

```
>cnako2 hanoi.nako
AからCへ移動
AからBへ移動
CからBへ移動
AからCへ移動
BからAへ移動
BからCへ移動
AからCへ移動

```

以上。
'"axios"' has no exported member named 'axios'. と出てしまう時の対処法[TypeScript、JavaScript]

axiosを使った際に、こんなエラーが出てしまいました。

```zsh:zsh
TS2724: '"axios"' has no exported member named 'axios'. Did you mean 'Axios'?
```

その時のコードは下のようになっていたのですが、ここでエラーが起きていました。

```typescript:typescript
import {axios, AxiosError} from 'axios';
```

このエラー解決で調べたことを書いていこうと思います。

# 原因

これは、axiosという***名前付きエクスポート***がないことが原因でした。

axiosはdefaultエクスポートされているモジュールであり。使用するには下のようのコードを修正する必要がありました。

```javascript
import axios,{AxiosError} from 'axios';
```

名前付きエクスポートとdefaultエクスポートはJavascriptの定義したモジュールを外部機能として提供する方法です。


名前付きエクスポートというのは、下のようなコードで定義されているモジュールや値を指します。

```javascript
export const
```

defaultエクスポートでは、下のようなコードで定義されているモジュールや値を指します。

```javascript
export default const
```

それぞれの特徴は下のようになっています。

||名前付きエクスポート|defaultエクスポート|
|---|---|---|
|モジュール|複数定義可能|一つだけ定義可能|
|インポートの{}	|必要|不必要|
|名前|エクスポート時の名前と合わせる|任意の名前に設定可能|

# 名前付きエクスポートとdefaultエクスポートの使い分け方

一般的に二つのエクスポートは以下のような使い分け方をします。

|エクスポート|使い方
|---|---
|名前付きエクスポート|一部分の機能だけを使わせたい時
|defaultエクスポート|メイン機能を提供したいとき

今回のエラーが出たのはNext.jsで執筆していた時に起きたのですが、Next.jsではメイン機能として提供するコンポーネント(page.tsxとか)はdefaultエクスポート、多くの箇所で使い回すコンポーネントは名前付きエクスポートで使い分けていました。

使い分け方のイメージとしてもしっくりくるなと個人的に思いました。
SeleniumでHTTP HEADERにパラメータ追加する方法

ChromeブラウザでHTTPリクエストヘッダーに独自のパラメータを追加する方法はいくつかあります。以下に説明します：

方法 1: Selenium DevTools Protocolを利用

SeleniumのDevTools Protocolを使うと、HTTPリクエストを直接操作してカスタムヘッダーを追加できます。

サンプルコード：

from selenium import webdriver

# Chrome Driverの作成
driver = webdriver.Chrome()

# DevToolsプロトコルを有効化
driver.execute_cdp_cmd("Network.enable", {})

# カスタムHTTPヘッダーを設定
driver.execute_cdp_cmd("Network.setExtraHTTPHeaders", {
    "headers": {
        "Custom-Header": "CustomValue",  # 独自のパラメータ
        "Another-Header": "AnotherValue"
    }
})

# ターゲットURLを開く
driver.get("https://example.com")

# ブラウザを終了
driver.quit()

方法 2: Chrome拡張機能を使用

Modify HeaderなどのChrome拡張機能や自作の拡張を使ってリクエストヘッダーを変更・追加できます。

自作拡張の例：
	1.	manifest.jsonを作成：

{
  "manifest_version": 3,
  "name": "Add Custom Header",
  "version": "1.0",
  "permissions": ["webRequest", "webRequestBlocking", "storage", "activeTab"],
  "host_permissions": ["<all_urls>"],
  "background": {
    "service_worker": "background.js"
  }
}

	2.	background.jsでヘッダーを追加：

chrome.webRequest.onBeforeSendHeaders.addListener(
  function(details) {
    details.requestHeaders.push({name: "Custom-Header", value: "CustomValue"});
    return {requestHeaders: details.requestHeaders};
  },
  {urls: ["<all_urls>"]}, // 全てのURLを対象
  ["blocking", "requestHeaders"]
);

	3.	Seleniumで拡張機能を読み込む：

from selenium import webdriver

options = webdriver.ChromeOptions()
options.add_argument("--load-extension=/path/to/your/extension")  # 拡張機能のパス

driver = webdriver.Chrome(options=options)
driver.get("https://example.com")

方法 3: プロキシを使ってリクエストを改変

MitmproxyやFiddlerなどのプロキシツールを使えば、リクエストを傍受してヘッダーを追加できます。

サンプルコード（Mitmproxyスクリプト）：
	1.	modify_headers.pyというスクリプトを作成：

from mitmproxy import http

def request(flow: http.HTTPFlow) -> None:
    flow.request.headers["Custom-Header"] = "CustomValue"

	2.	SeleniumでMitmproxyを利用：

from selenium import webdriver

options = webdriver.ChromeOptions()
options.add_argument("--proxy-server=http://127.0.0.1:8080")  # Mitmproxyのプロキシアドレス

driver = webdriver.Chrome(options=options)
driver.get("https://example.com")

Mitmproxyを起動すると、すべてのリクエストが改変されます。

方法 4: fetchまたはXMLHttpRequestでヘッダーを変更

JavaScriptを直接実行できる場合、fetchやXMLHttpRequestを使ってヘッダーを追加できます。

サンプル：

fetch("https://example.com", {
  method: "GET",
  headers: {
    "Custom-Header": "CustomValue"
  }
}).then(response => response.text())
  .then(data => console.log(data));

このスクリプトをSeleniumのexecute_scriptでブラウザ内に実行：

script = """
fetch("https://example.com", {
  method: "GET",
  headers: {
    "Custom-Header": "CustomValue"
  }
}).then(response => response.text())
  .then(data => console.log(data));
"""
driver.execute_script(script)

まとめ
	•	ブラウザ全体でカスタムヘッダーを使いたい場合：Chrome拡張を使うのがおすすめ。
	•	自動化が目的の場合：SeleniumのDevTools Protocolが最も簡単。
	•	柔軟性を重視する場合：Mitmproxyなどのプロキシツールを利用。
selenium如何更改request的header

在使用 Selenium 时，直接更改请求的 header 并不容易，因为 Selenium 本身是一个浏览器自动化工具，主要用于模拟用户操作，而浏览器的请求头（Request Headers）通常由浏览器自行管理。

不过，你可以通过以下几种方法来修改请求头：

方法 1: 使用 webdriver.ChromeOptions 设置某些 headers

如果你需要设置 User-Agent，可以通过 ChromeOptions 配置：

from selenium import webdriver

options = webdriver.ChromeOptions()
options.add_argument("user-agent=Custom User-Agent String")

driver = webdriver.Chrome(options=options)

# 启动浏览器并访问目标页面
driver.get("https://example.com")

方法 2: 使用浏览器扩展修改 headers

通过加载一个修改请求头的浏览器扩展，可以动态更改所有请求的 headers。
例如：Modify Header Value 插件或自己写一个。

简单示例：
	1.	编写扩展的 manifest.json：

{
  "manifest_version": 2,
  "name": "Modify Headers",
  "version": "1.0",
  "permissions": ["webRequest", "webRequestBlocking", "<all_urls>"],
  "background": {
    "scripts": ["background.js"]
  }
}

	2.	编写 background.js 修改 header：

chrome.webRequest.onBeforeSendHeaders.addListener(
  function(details) {
    details.requestHeaders.push({name: "Custom-Header", value: "CustomValue"});
    return {requestHeaders: details.requestHeaders};
  },
  {urls: ["<all_urls>"]},
  ["blocking", "requestHeaders"]
);

	3.	使用 Selenium 加载这个扩展：

from selenium import webdriver

options = webdriver.ChromeOptions()
options.add_argument("--load-extension=/path/to/extension")

driver = webdriver.Chrome(options=options)
driver.get("https://example.com")

方法 3: 使用代理修改请求头

通过代理工具（如 Mitmproxy 或 Fiddler），可以拦截请求并动态修改 headers。

示例：结合 Selenium 和 Mitmproxy
	1.	编写 Mitmproxy 脚本修改 headers：

from mitmproxy import http

def request(flow: http.HTTPFlow) -> None:
    flow.request.headers["Custom-Header"] = "CustomValue"

	2.	配置 Selenium 使用 Mitmproxy：

from selenium import webdriver

options = webdriver.ChromeOptions()
options.add_argument("--proxy-server=http://127.0.0.1:8080")  # Mitmproxy 默认端口

driver = webdriver.Chrome(options=options)
driver.get("https://example.com")

启动 Mitmproxy 后，运行 Selenium 会经过代理拦截，Headers 会被修改。

方法 4: 使用 DevTools Protocol

通过 Selenium 的 DevTools Protocol，可以拦截并修改请求，包括自定义 Headers：

from selenium import webdriver

driver = webdriver.Chrome()

# 启用 DevTools
driver.execute_cdp_cmd("Network.enable", {})

# 修改 Headers
driver.execute_cdp_cmd("Network.setExtraHTTPHeaders", {
    "headers": {
        "Custom-Header": "CustomValue",
        "User-Agent": "Custom User-Agent"
    }
})

# 打开目标页面
driver.get("https://example.com")

总结

如果只是修改部分 headers（如 User-Agent），直接用 ChromeOptions 最简单；如果需要复杂的定制，推荐使用 DevTools Protocol 或代理工具。