OmniAICreator/Qiita-1.07M huggingface dataset:
Outlook on the web デスクトップ通知の設定と表示時間の変更

## はじめに
Outlook on the webで、メールを受信した際のデスクトップ通知について、以下の相談を受けた。

マシン:dynabook B55/KW
OS：Windows11
ブラウザ:Microsoft Edge

- Outlook on the webを開いている時にしか通知が表示されない
- 右上に一瞬だけ通知が表示され、すぐに消えてしまう

だが、自身のPCのOutlook on the Webでは、機種は違うが、同じWindows11のMicrosoft Edgeで、開いていなくても通知は表示されており、デスクトップ通知の位置は右下で、Windowsの設定でデスクトップ通知の表示時間も変更できた。
そのため、なんらかの設定が違うのではと思い、調べた結果をまとめておく。

## Outlook on the web デスクトップ通知の設定
設定の違いは、Outlook on the webの「通知」の「メール」の「通知スタイル」の違いだった。
この通知スタイルが「アラート」だったため、「はじめに」に記載した現象が発生していた。
この通知のスタイルを「ブラウザー」に変更して設定を保存する。
ポップアップで表示されるブラウザーからの確認画面で許可を押す。
すると、デスクトップ通知が右下に表示され、これで、起動していなくても、通知が表示されるようになる。

【Outlook on the web 通知のスタイル 設定画面】
![outlook 通知設定.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3917113/3795cc6a-8567-4049-82a0-f4a16082af56.jpeg)

【ブラウザー確認画面】
![ブラウザー確認画面.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3917113/9b887f83-da50-406b-8958-c92a0ebcdc3a.jpeg)

【デスクトップ通知】
![デスクトップ通知.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3917113/0d3d5d42-b4b0-4be9-9ae5-f992cfb139b9.jpeg)

## デスクトップ通知の表示時間の変更
デスクトップ通知の表示時間の変更については、Windowsの設定から変更する。
「設定」⇒「アクセシビリティ」⇒「視覚効果」⇒「この時間が経過したら通知を破棄する」
表示時間については、5秒、7秒、15秒、30秒、1分、5分から選択することができる。
ただし、この設定はOutlook on the webに限らず、全てのデスクトップ通知に適用される。

【設定画面1】
![設定画面.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3917113/9f49f9ad-41f0-4761-be6a-1a12d152a65b.jpeg)


【設定画面2】
![設定画面2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3917113/07a870d4-3623-474e-9750-66c5495d214d.jpeg)


## 参考
- [デスクトップ通知の方法 | Livestyleクラウドサービス](https://live-style.jp/desktop-notification-method/ "デスクトップ通知の方法 | Livestyleクラウドサービス")
- [通知メッセージの表示時間を変更する方法 | ドスパラ サポートFAQ よくあるご質問](http://faq3.dospara.co.jp/faq/show/8376?category_id=1&site_domain=default "通知メッセージの表示時間を変更する方法 | ドスパラ サポートFAQ よくあるご質問")
TypeScript:1.div要素の取得（querySelectorAll）

## TypeScriptでdiv要素を取得しよう
TypeScriptでdocument.querySelectorAll()でdivを取得して代入する書き方は火のようになる。

```TypeScript:exe.ts
const divs = document.querySelectorAll<HTMLDivElement>('div');
```
### 補足説明：
・querySelectorAllは返り値としてNodeListを返す（配列っぽいけど配列じゃない）。
・<HTMLDivElement>と書くことで、取得する要素の型を明示できる（typeScriptの利点）
・divsの型はNodeListOf<HTMLDivElement>になる

もし特定のdivクラスだけ取得したい場合は以下のようにセレクタを変える
```TypeScript:exe.ts
const specialDivs = document.querySelectorAll<HTMLDivElement>('div.special');
```

## ＜HTMLDivElement＞と定義する理由
document.querySelectorAll('div')だけだと、TypeScriptは具体的にどのタグかを判断できず、汎用的なElement型として扱う
しかし、実際にやりたいことはTypeScriptが＜div＞と判断しHTMLDivElementのプロパティを使用できる状態になること。

例：型を指定しない場合
```TypeScript:exe.ts
const divs = document.querySelectorAll('div');

divs.forEach(div => {
    div.style.backgroundColor = 'blue'; //エラーになる可能性がある
});
```
例：型を指定する場合
```TypeScript:exe.ts
const divs = document.querySelectorAll<HTMLDivElement>('div');

divs.forEach(div => {
    div.style.backgroundColor = 'blue'; //問題なし
});
```
この場合だとTypeScriptはHTMLDivElementと判断し.styleや.innerHTMLの使用を許可することができる
ubuntu 24.04 環境が崩壊してしまった件（現在回復途中）

## 不幸の始まり、それは libpango-1.0.0 からやってきた。
いろいろ無理なことを python絡み、mkdocs にかかる話で進めていたのだが、うっかりpango 周りのライブラリを壊したようで、そこから不幸が始まりました。

## Xfce-erminal がコケる！
こうなると、logを見るほかありません。
```
2025-03-22T11:18:59.984472+09:00 ubuntu-pc kernel: xfce4-terminal[9768]: segfault at 0 ip 00007799b9a696f4 sp 00007fff93ed7848 error 4 in libpango-1.0.so.0.5200.1[7799b9a57000+39000] likely on CPU 13 (core 5, socket 0)
```
* 原因は libpango-1.0.so.0.5200.1 にあるようなのですが、これが新しいのか古いのか、そもそも pangoだけの問題かよくわかりません。

## "apt --fix-broken install" しろと出たのでやっちゃった・・・
* gir1.2 から脱落していく・・・ああなんてこと。
* pangoばかりかGUI環境の崩壊が始まってしまいました・・・他にもいろいろだめだったらしい。

## こういうとき、焦ってはだめ。
* recovery を淡々とやる他ありません。
* ubuntuが調子悪くなるのは半年に一度[^1] で、多分いろいろアップデートが混ざってしまったのだと思います。 LTSだったら大丈夫だと思っていたのですがソフトウェア開発環境を手に入れ始めたときは要注意です[^2]

[^1]:要するに新バージョンリリースと同時
[^2]:管理業務用と開発用PCを別に用意するしかないです。

* いろいろやってますが、recovery がちょっと旨く行きません。
もうどうせなら、Ubuntu24.04を捨てて 24.10に行っちゃえ！と考えました[^3]
[^3]: 結局この判断で後悔することになります。

## ubuntu の更新方法
* LTS から 半年いっぺんの更新版にするには /etc/update-manager/release-upgrades の Prompt=lts となっている箇所を Prompt=normal に変更してから下記コマンドを実行します。
* この作業時間がかかるので、こんな陽気の良い日に籠もってウダウダ使えんPCの前にいるよりは外出 [^4]してしまえとなりました・・・
* サブ機[GhostBSD](https://www.ghostbsd.org)では、昨日の昼間からずーっぅと [Electron](https://www.electronjs.org/ja/docs/latest/) のコンパイルをやっています。こっちの記事を書こうにも、後残っているのは2015年版のMacBookAirだけで、もうイジる気力がない。

[^4]: この数年ロードバイクにハマって、一心不乱に踏んでいて気がつくと100kmくらい乗ってたりします。

## ⇒ 別の　"Display Manager" たちに浮気。
* lightdm が折悪しく復旧せず Xfceのグラフィカルログイン画面が戻ってきません。
* sddmを入れてみたのですが、 sddmは いわゆる黒画面になってしまって 昔ながらの console login から startx をする足場になってはいます。悪くないんですが・・
* 古き良きGnomeDesktop? などと銘打たれた  gdm3 を入れてみたのですが、XFce4に慣れているとちょっともどかしい。 Gnome環境に慣れても良いんですけど、Finder/MS-Windowsの流儀とはかなり違うもので、格好いいのかもだけど私のようなGUI老人には無理。
* slim だと、２画面のどまんなか..要するに泣き別れた状態になってしまいます。しかも画面の左右がフリップサイドして完全に分裂！　非常にやりにくい。それでも XFce4-wmにはつなげてくれます。 FreeBSDだとslim+XFce4だったのでまあ有りっちゃありなんですが、どうしてくれよう。

## 現状・・・　ちょっと悲惨な状況。
* まぁいろいろあって　Ubuntu24.10 にはなったのですが、問題発生です。 [Virtualbox7.1](https://www.virtualbox.org/) が動かなくなっていました。　というかインストールすることは出来るんです。やり方はゴニョゴニョ[^5]
[^5]:[VirtualBoxのforum記事](https://forums.virtualbox.org/viewtopic.php?t=112588) に インストールする shell-archiveがあるということで、インストールはしたんですが これって結局、後々 apt --fix-broken install しろってうるさい事になるのです・・・
* mozc が動かなくなっていました。 ibus版のmozcを入れ直して取り敢えずというところ。fctix版でもいいんですが、もうibus枯れてるしそれでいいと。
* Thunar にも問題が発生していました。これは [udiskie](https://github.com/coldfix/udiskie) が抜けたため、主DISK以外のSSD/HDDを Thunarからクリックひとつで マウントすることが出来ないというものです。　これは勝手に入ってて気にしていなかったのですが、いざなくなるとほんとに困る。
* VirtualBox7.1 をちゃんと動かすには、コンパイルするしか無いんでしょう。これはしんどい話です。どこぞで非公式のバイナリが転がっていませんか。教えてください。[^6]
[^6]: [ダウンロードサイト](https://download.virtualbox.org/virtualbox/7.1.6/virtualbox-7.1_7.1.6-167084~Ubuntu~oracular_amd64.deb)　がありました。取り敢えず試して見るところ。
---
## 教訓：Ubuntu こわれたらその問題解決＝ほころびを探すより新しいSSDを買って更地にOSを入れたほうが多分楽だ。

* [真面目に全部コンパイルからUbuntuの構築をやる方法](https://github.com/mvallim/live-custom-ubuntu-from-scratch) というのもあるにはあるんです。それはとてもしんどい話と思っています。FreeBSDでも散々やって今も結構CPUタイムを食うのでこのコストを払う価値のある仕事になっていなければやらないほうが良いでしょうね。
* ともあれ、業務用サーバではもうコンテナ化で依存系トラブルがなくなったので、デスクトップでもそうしたいんですが、何せSSDの容量が足りない・・何でもコンテナに入れてたら、コンテナの作りが悪くてオーバヘッドでSSDがいっぱいなんてことはあります。
* snapがコンテナっぽいので、snap使えよという話でしょう。apt/dpkg でゴリゴリやるのはもうやめたほうが良いのかもですね。という結論。
基本的なMOSデバイス物理学

アナログCMOS集積回路の設計基礎編

Chapter 2
Basic MOS Device Physics
---
### 第2章: 基本的なMOSデバイス物理学

---

### **概念のまとめ**

1. **デプレッション領域の広がりとポテンシャルの変化**:
   - ゲート電圧 (**VG**) が増加すると、デプレッション領域の幅が広がり、酸化膜界面のポテンシャルも増加します。この時、構造はゲート容量とデプレッション電荷容量の直列接続に似た形になります。
   - さらに**VG**が増加すると、インターフェースの電位は完全に正の値に達し、電荷キャリアがソースからインターフェースを経由してドレインに流れます。このとき、電荷キャリアの「チャネル」が逆転して流れが開始され、トランジスタがON状態になります。

2. **しきい値電圧 (Vth) の定義**:
   - **Vth**は「しきい値電圧」と呼ばれ、ゲート電圧がこの値を超えると、電荷キャリアの密度が増加し、ドレインからソースへの電流が流れ始めます。

3. **実際のVthの変化**:
   - 実際には、**Vth**は急激に増加するのではなく、滑らかに増加します。このため、**Vth**を正確に定義するのが難しく、半導体デバイスでは通常、NFET（n型MOSトランジスタ）において、基板がp型であるときに**Vth**を定義します。

4. **Vthの数式**:
   - しきい値電圧**Vth**は以下のように定義されます：
     \[
     V_{th} = \Phi_{MS} + 2\Phi_F + \frac{q\Delta\varphi}{C_{ox}}
     \]
   - **ΦMS**はポリシリコンゲートとシリコン基板の仕事関数の差であり、**ΦF**はFermiポテンシャル、**Δφ**はデプレッション領域内の電位変化です。また、**Cox**はゲート容量です。

5. **Vthの変動要因**:
   - 基板がn型である場合、ゲート電圧が増加すると、デバイスの動作に影響を与えるため、ゲート容量や基板の種類に基づいてしきい値電圧が決まります。

---

### **式の解説**

#### **I = Q₀ ⋅ v**
この式は、半導体バー内で電流が運ばれる様子を示しています。式の意味を分解していきます。

- **I (電流)**: **I**は電流の大きさを示し、単位時間あたりに流れる電荷量です。単位はアンペア（A）。
- **Q₀ (クーロン/メートル)**: **Q₀**は、半導体バー内で1メートルあたりに存在する電荷量を示します。単位はクーロン（C）。
- **v (速度)**: **v**は電荷キャリアの速度を示し、単位はメートル毎秒（m/s）。

この式は、電流が電荷密度とその移動速度によって決まることを表しています。

---

### **1. ドレイン電流の関係式 (式 2.24)**

\[
I_D = \frac{W}{L} \cdot \mu_n C_{ox} \left[ V_{GS} - V_{TH} - \gamma \left( \sqrt{2\Phi_F + V_{SB}} - \sqrt{2\Phi_F} \right) \right]
\]

- **I_D**: ドレイン電流
- **W/L**: チャネルの幅と長さの比
- **μ_n**: 電子の移動度
- **C_ox**: ゲート酸化物の容量
- **V_GS**: ゲートとソース間の電圧
- **V_TH**: しきい値電圧
- **V_SB**: ソースと基板間の電圧
- **Φ_F**: Fermiポテンシャル
- **γ**: ボディ効果係数

#### **解説**:
この式は、MOSFETのドレイン電流を計算するためのものです。ゲート-ソース間電圧 **V_GS** がしきい値電圧 **V_TH** より大きくなると、トランジスタがONになり、電流が流れます。この式では、ボディ効果（**γ**）やソースと基板間の電圧（**V_SB**）の影響も考慮されています。

---

### **2. モデリング式（式 2.25）**

\[
I_1 = \frac{W}{2\mu_n C_{ox} L} \cdot V_{DD} \cdot (V_{in} - V_{out})^2
\]

- **I_1**: 出力電流
- **W/L**: チャネルの幅と長さの比
- **μ_n**: 電子移動度
- **C_ox**: ゲート酸化物容量
- **V_DD**: 電源電圧
- **V_in**: 入力電圧
- **V_out**: 出力電圧

#### **解説**:
この式は、MOSFETの動作をモデル化したもので、入力電圧と出力電圧の差によって出力電流が決まることを示しています。このモデルは、MOSFETの動作を簡潔に表現しています。

---

### **3. チャネル長モジュレーション式 (式 2.26)**

\[
I_D = \frac{W}{L} \cdot \mu_n C_{ox} \left( V_{GS} - V_{TH} \right) \cdot \left( 1 + \lambda V_{DS} \right)
\]

- **I_D**: ドレイン電流
- **W/L**: チャネルの幅と長さの比
- **μ_n**: 電子の移動度
- **C_ox**: ゲート酸化物容量
- **V_GS**: ゲートとソース間の電圧
- **V_TH**: しきい値電圧
- **λ**: チャネル長モジュレーション係数
- **V_DS**: ドレインとソース間の電圧

#### **解説**:
チャネル長モジュレーションは、ドレイン電圧が増加すると、チャネル長が縮む現象です。これにより、ドレイン電流 **I_D** が増加します。式の中の**λ**は、この効果を示すモジュレーション係数です。

---

### **4. サブスレショルド動作式 (式 2.30)**

\[
I_D = I_0 \exp \left( \frac{V_{GS}}{V_T} \right)
\]

- **I_D**: ドレイン電流
- **I_0**: 基準電流
- **V_GS**: ゲートとソース間の電圧
- **V_T**: しきい値電圧

#### **解説**:
サブスレショルド動作は、しきい値電圧以下で動作するMOSFETの特徴的な動作です。サブスレショルド領域では、電流が指数関数的に増加します。この式は、その関係を示しています。

---

### **まとめ**

- **MOSFET**におけるさまざまな現象とその影響を計算するための式を紹介しました。これらの式は、トランジスタの性能や動作特性を理解するのに不可欠です。
- **ボディ効果**や**チャネル長モジュレーション**などの重要な現象が、MOSFETの動作にどのように影響を与えるかを理解するために、これらの式を使用します。
📝基本情報技術者試験(FE)~~💯「PaaS・SaaS・IaaSの違いとは？クラウドサービスモデル？」

PaaS、SaaS、IaaS は、クラウドコンピューティングのサービスモデルを分類したものです。それぞれの特徴を説明します。  

---

## **1. SaaS（Software as a Service）**  
**ソフトウェアをインターネット経由で提供するサービス。**  
- **ユーザーはインストールや管理をせずに、すぐに利用可能。**  
- **アプリケーションの管理はクラウド提供者が行う。**  
- 例:  
  - **Google Workspace（Gmail, Google Drive, Google Docs など）**  
  - **Microsoft 365（Word, Excel, Teams など）**  
  - **Dropbox（クラウドストレージ）**  
  - **Salesforce（CRM）**  

**✓ メリット:**  
- すぐに使える（導入が簡単）。  
- ソフトウェアの更新や管理が不要。  
- どこからでもアクセス可能。  

**✗ デメリット:**  
- カスタマイズ性が低い。  
- インターネット接続が必要。  
- データがクラウド側にあるため、セキュリティリスクがある。  

---

## **2. PaaS（Platform as a Service）**  
**アプリケーション開発のためのプラットフォームを提供するサービス。**  
- **開発者はインフラ管理をせずに、アプリケーションの開発・実行が可能。**  
- **開発環境、データベース、ミドルウェアなどをクラウド側が提供。**  
- 例:  
  - **Google App Engine（Google Cloud）**  
  - **AWS Elastic Beanstalk（Amazon Web Services）**  
  - **Microsoft Azure App Service**  
  - **Heroku**  

**✓ メリット:**  
- サーバー管理不要で、開発に集中できる。  
- 環境構築が不要で、スピーディーに開発できる。  
- スケーラブルで、自動的にリソースを増減できる。  

**✗ デメリット:**  
- 提供される環境に依存するため、自由度が低い。  
- 特定のクラウドベンダーにロックインされる可能性がある。  

---

## **3. IaaS（Infrastructure as a Service）**  
**仮想マシンやストレージ、ネットワークなどのインフラを提供するサービス。**  
- **物理サーバーを購入せずに、クラウド上でサーバーを作成・管理できる。**  
- **OSやミドルウェアの設定・管理はユーザーが行う。**  
- 例:  
  - **Amazon EC2（AWS）**  
  - **Google Compute Engine（GCP）**  
  - **Microsoft Azure Virtual Machines**  
  - **IBM Cloud**  

**✓ メリット:**  
- 物理サーバーを購入せずに、柔軟にリソースを増減できる。  
- 必要に応じてカスタマイズが可能。  
- クラウド上で自由に環境を構築できる。  

**✗ デメリット:**  
- OSやソフトウェアの管理が必要。  
- ネットワークやセキュリティ設定を自分で行う必要がある。  

---

## **SaaS / PaaS / IaaS の違い（まとめ）**  

| **種類**  | **提供内容**  | **ユーザーの管理範囲**  | **例**  |
|----------|------------|----------------|------|
| **SaaS** | ソフトウェア（アプリ） | なし（利用するだけ） | Gmail, Dropbox, Salesforce |
| **PaaS** | 開発環境・プラットフォーム | アプリケーション開発のみ | Google App Engine, Heroku |
| **IaaS** | 仮想マシン・インフラ | OS・ミドルウェア・アプリ管理 | AWS EC2, Azure VM |

---

### **どれを選ぶべきか？**
- **手軽にソフトウェアを使いたい → SaaS**  
- **アプリを開発・実行したいが、インフラ管理はしたくない → PaaS**  
- **自由にインフラを構築・管理したい → IaaS**  

どのサービスを選ぶかは、目的や技術レベルによって変わります。


https://qiita.com/SMZPP/items/ac9ce8d1b398a7ee44e6
Raycastの「AI Chat」で画像生成をする

こんにちは。せーじです。普段はWebやバックエンド、時々アプリの開発をしています。  
私は業務や私生活で日常的に[Raycast](https://www.raycast.com/)を使っています。

Raycastの充実したAIまわりの機能も、プロダクトとして目指す姿も好きですが最近驚いたことがありました。

# Raycastの「AI Chat」機能から画像生成ができない、、、:sob:

:::note info
記事執筆時のRaycastのバージョンは1.94.0です。
:::

少なくとも 2025年1月27日↓にはできていたはずの画像生成ができなくなっていました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3948850/406f9979-501f-4a54-ab68-525f78c6dab5.png)

現状ではかわりにWeb検索をするようになっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3948850/ba35448e-aa7d-4586-acfe-f487aa022b44.png)

# Raycastの「AI Chat」で画像生成をする

画像生成の方法を色々調べていたところ、「Create AI Chat Preset」の一番下に「AI Tools」という項目があり、「Image Genaration - DALL・E　3」にチェックを入れることで画像生成ができるようになりました。

リリースノートで仕様変更に関するドキュメントは見つけられませんでしたが、おそらくAI Extention(Beta)がリリースされた、 [Release v1.93.0](https://www.raycast.com/changelog/1-93-0)あたりで使用の変更があったのではないかと思います。

:::note warn
画像の生成はRay-1および、GPT-4系のモデルなどが利用できました。
逆にGPT-o3やGemini, Deepseek, Mistralなどモデルでは利用できませんでした。
:::

![Raycast 2025-03-22 at 18.58.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3948850/774493f6-2697-4109-9c25-952502b3c030.png)

![Raycast 2025-03-22 at 18.59.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3948850/4a94fbf7-5cfb-48e6-a0e7-5bb84755c7cc.png)


# 終わりに
AI関連の機能はRaycast Pro($8/month)ににならないと使えない機能ですが、[Free Trial](https://www.raycast.com/pricing)もできます。

興味が湧いた方は試してみてください！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3948850/12999162-2de0-4a1e-9e10-55c8d0f90053.png)
React Hook Formでバリデーションを実装

## インストール用コマンド

```
npm install react-hook-form
```

## フォームの実装方法

```
// useFormをインポート
import { useForm } from "react-hook-form";

// useFormからregisterとhandleSubmitを呼び出す
const { register, handleSubmit } = useForm();

// onSubmitを定義(本来は引数dataの型はしっかり定義する)
const onSubmit = (data: any) => {
    console.log(data);
};
// フォーム全体にhandleSubmitを適用する
<Box component={"form"} onSubmit={handleSubmit(onSubmit)}>
    // 中身は省略
</Box>
```

## バリデーションの実装方法

### 用意されているバリデーション
下記のようなフォームでよく使われるバリデーションは用意されている。
- required：　"必須入力"
- max：　"最大値"
- min：　"最小値"
- maxLength：　"最大文字数"
- minLength：　"最小文字数"
- pattern：　"正規表現(メールアドレスなど)"

＜例＞
```
<Controller 
    {...register('content', {
        required: '内容を入力してください。',
        maxLength: {
        value: 50,
        message: '内容は50文字以内で入力してください。'
        }
    })}
    control={control}
    render={({ field }) => (
        <TextField 
        {...field}
        error={!!errors.content}
        helperText={errors.content?.message as string}
        label="内容"
        type="text" />
    )}
/>
```

### オリジナルで作成できるバリデーション

```
<Controller 
    {...register('amount', {
        validate: (data) => {
            if (data === 0) {
                return '金額を入力してください。'
            }
        }
    })}
    control={control}
    render={({ field }) => (
        <TextField
        {...field}
        value={field.value === 0 ? "" : field.value}
        onChange={(e) => {
            const newValue = parseInt(e.target.value) || 0
            field.onChange(newValue)
        }}
        error={!!errors.amount}
        helperText={errors.amount?.message as string}
        label="金額"
        type="number" />
    )}
/>
```

## エラー処理

```
// useFormからerrorsオブジェクトを取り出す
const {
    register,
    formState: { errors },　// useFormに追加
    handleSubmit,
  } = useForm();

// 各フォームのinput要素(TextFieldにエラーを表示)
<TextField 
　error={!!errors.content}
　helperText={errors.content?.message as string}
/>
```

以上
ABC398をPythonで（A～D、F）

ユニークビジョンプログラミングコンテスト2025 春（AtCoder Beginner Contest 398）の解答等の速報的まとめ

https://atcoder.jp/contests/abc398



# A問題
https://atcoder.jp/contests/abc398/tasks/abc398_a

\-を半分くらい埋めて=をいい感じにする
```python:A
n = int(input())
s = (n - 1) // 2
print("-" * s + "=" * (1 if n % 2 else 2) + "-" * s)
```
# B問題
https://atcoder.jp/contests/abc398/tasks/abc398_b

3枚以上ある数の存在とペアをつくれる数が（3枚以上あるものも含め）２種類以上あるか調べる
```python:B
A = list(map(int, input().split()))

d = dict()
for a_i in A:
    if a_i not in d:
        d[a_i] = 0
    d[a_i] += 1

three_flag = False
two_count = 0
for val in d.values():
    if val >= 2:
        two_count += 1
    if val >= 3:
        three_flag = True

print("Yes" if three_flag and two_count >= 2 else "No")
```
# C問題
https://atcoder.jp/contests/abc398/tasks/abc398_c

１つしかない数の中で最大のものを求め、その場所を出力する
```python:C
n = int(input())
a = list(map(int, input().split()))

d = dict()
for a_i in a:
    if a_i not in d:
        d[a_i] = 0
    d[a_i] += 1

ans = -1
for key, val in d.items():
    if val == 1:
        ans = max(ans, key)

print(ans if ans < 0 else a.index(ans) + 1)
```
# D問題
https://atcoder.jp/contests/abc398/tasks/abc398_d

煙でなく焚き火と高橋君を動かして調べる
```python:D
n, r, c = map(int, input().split())
s = input()

smoke = {(0, 0)}
x, y = 0, 0
arr = {"N":(1, 0), "S":(-1, 0), "W":(0, 1), "E":(0, -1)}
ans = list()
for s_i in s:
    x += arr[s_i][0]
    y += arr[s_i][1]
    smoke.add((x, y))
    ans.append("1" if (r + x, y + c) in smoke else "0")

print(*ans, sep="")
```
# F問題
https://atcoder.jp/contests/abc398/tasks/abc398_f

後ろから切り取って最長になる回文を求め、そうでない場所を後ろに反転させて繋げたものが答え
回文判定はdequeで行う
```python:F
from collections import deque


def answer(s):
    print(*s, sep="")

s = list(input())
n = len(s)
ans = n - 1
s_ = s.copy()
t_right = deque()
t_left = deque()
while s_:
    s_i = s_.pop()
    t_right.append(s_i)
    t_left.appendleft(s_i)
    if t_right == t_left:
        ans = len(s_)

answer(s + s[:ans][::-1])
```
AndroidStudioでAnalysis server has terminated.を解決する

## エラー本文
```
Analysis server has terminated
```

## 事象
- `flutter upgrade`やfvmでFlutterのバージョンアップをした際に発生
- Flutterの補完が効かない

## 解決したコマンド
```sh
rm -rf .dart_tool pubspec.lock
flutter pub get
```

## 効果がなかったこと
- Android Studio再起動
- Android Stugioのキャッシュクリア　
    - File > Invalidate Caches / Restart... > Invalidate and Restart
- 以下のコマンド
```sh
flutter pub cache repair
flutter clean
flutter pub get
```
```sh
flutter upgrade --force
```
AtCoderをPythonで取り組んだ振り返り(ABC398 A～C)

どうもこんにちは！

今週もAtCoderのコンテストに参加できたので、記録がてら振り返ります。
今回はCまで完答。Cは解けたり解けなかったりしています。

# 問題
問題は以下のリンクから。取り組めたA~Cまでを振り返ります。

https://atcoder.jp/contests/abc398/tasks

# A - Doors in the Center -
文字列の長さnが与えられるので、以下の条件を満たす文字列を出力するというもの。
　・文字列は - または =で構成。=は1個または2個で2個含まれる場合は隣接する。
　・回文
これを満たすのは=が中心にあり前後に-が同数となる場合で、文字列が奇数なら=は1個、偶数なら2個となる場合。
文字列が奇数と偶数で場合分けして出力するようにしました。
~~~Python
n = int(input())
if n % 2 == 1:
  s = '-'*((n-1)//2) + '=' + '-'*((n-1)//2)
else:
  s = '-'*((n-2)//2) + '==' + '-'*((n-2)//2)
print(s)
~~~

# B - Full House 3 -
与えられた7個の値から、それを組み合わせてフルハウスが作れるかを判定するという問題。(フルハウスはポーカーに出てくる役の1つで、ある数字が3個と別の数字が2個の組み合わせです)
7個の値の集合から、3個以上ある値と2個以上ある値の両方が存在するかどうかを判定するとしました。
~~~Python
s = [int(x) for x in input().split()]
cards_3 = False
cards_2 = False

for i in set(s):
  if s.count(i) >= 3 and cards_3 == False:
    cards_3 = True
  elif s.count(i) >= 2:
    cards_2 = True
    
if cards_3 and cards_2:
  print("Yes")
else:
  print("No")
~~~

# C - Uniqueness -
N人がそれぞれ1個の値を持っていて、ほかの人が誰も持っていない値を持っている人のうち、最大の値を持っている人が何番目かを出力するという問題。(持っている値の最大値そのものを出力するではないです)
人数の最大は$3×10^5$、人が持つ値の最大は$10^9$です。
下記の手順で解きました。
　１．配列の値をすべて見て、カードの値とそれを持っている人が何番目かを保持するディクショナリを作成。複数人が持っているカードは値を-1にして区別。
　２．ディクショナリから1人だけ持っているカードの数値を抽出し、その値を出力

~~~Python
n = int(input())
s = [int(x) for x in input().split()]
count = {}

for i in range(n):
  if s[i] not in count:
    count[s[i]] = i+1
  else:
    count[s[i]] = -1

card = -1
for key,value in count.items():
  if value != -1:
    card = max(card,key)

if card == -1:
  print(-1)
else:
  print(count[card])
~~~



# おわりに
3問目が解けたり解けなかったりですが、解けても残り30分も無くDにとりかかる余裕ないのが現状です。3月中のコンテストはあと1回、4問完答が第一目標ですが、Cまでは確実に完答できるようになることと、C完答時点で50分程度は残すことも目先の目標にして、引き続き取り組んでいきたいと思います。

ではでは。
AWSが展開するメディアサービスカテゴリのサービスの一覧

## はじめに
AWSが展開するメディアサービスカテゴリのサービスの一覧についてまとめてみました。

## メディアサービスカテゴリ
　AWSクラウドを使って、動画配信やライブストリーミングおよび、動画フォーマットの変換や広告挿入などの編集が出来るサービス群。

## Amazon Elastic Transcoder
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387980/7153e587-8e41-4fc1-af87-bf41a317597c.png)
動画ファイルを様々なデバイスに対応した動画ファイルへ変換出来るサービス。

## AWS Elemental Appliances & Software

AWSの動画配信サービスと連携するためのオンプレミス向けソリューション。オンプレミスで動画アセットをエンコード、パッケージ化して、動画配信サービスとシームレスに接続する。

## AWS Elemental MediaConnect
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387980/4dc6297a-2f64-4bf5-929d-6511ff5d9dab.png)
AWSグローバルネットワークを通じて安全に複数の送信先に送信出来る高品質なライブ動画伝送サービス。

## AWS Elemental MediaConvert
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387980/04d1db15-e6c0-41b4-95d9-dcdeefeec2cf.png)
動画ファイルのブロードキャスト配信や変換・高度な編集が出来るサービス。

## AWS Elemental MediaLive
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387980/9e9f5529-80c5-48b9-aca0-e6ac8fa8e2fe.png)
高品質のライブ動画ストリームを信頼性の高い使いやすい方法で高速配信する、クラウドベースのライブ動画エンコードサービス。

## AWS Elemental MediaPackage
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387980/9fd3dea0-d9ce-4437-836b-a2dad1458ea2.png)
配信環境に応じて様々なフォーマットや、データ保護のための暗号化などを提供するサービス。

## AWS Elemental MediaStore
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387980/3dfdeaaf-ae17-44f6-ae97-153ed4a017d7.png)
メディア配信向けに高速化・最適化されたストレージサービス。

## AWS Elemental Media Tallor
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387980/66de8fc1-6a11-48b6-9cbc-0a52f36be733.png)
ビデオストリームに広告を個別に挿入するサービス。

## Amazon Interactive Video Service
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387980/302a3e63-babc-43ba-b5b7-3fcf4696af7c.png)
ライブ動画配信でコンテンツの取り込み、処理、配信までの動画ワークフローを一括でまとめられるソリューション。

## Amazon Nimble Studio
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387980/d9c6b2ec-4077-4b9c-b4ab-b7d4718a601f.png)
映画やアニメーションのクリエイティブスタジオなどで使用されるワークステーションやソフトウェア、ツールなどの作業環境セットをAWSクラウド上で提供するサービス。




## おわりに
ここまで読んでいただきありがとうございます！

## 参考文献
・AWSの基本・仕組み・重要用語が全部わかる教科書 (見るだけ図解) 単行本（ソフトカバー） – 2022/8/23
川畑光平 (著), 菊地貴彰 (著), 真中俊輝 (著)
p.61-62
GraphAI ~Google STT~

## GraphAIでGoogle STTを行うエージェントを作る

```typescript
import { AgentFunction, AgentFunctionInfo } from "graphai";
import { SpeechClient, protos } from "@google-cloud/speech";
import { GraphAINullableText } from "@graphai/agent_utils";

type STTGoogleInputs = {
  stream: Buffer;
  languageCode?: string;
  sampleRateHertz?: number;
  encoding?: "FLAC" | "ENCODING_UNSPECIFIED" | "LINEAR16" | "MULAW" | "AMR" | "AMR_WB" | "OGG_OPUS" | "SPEEX_WITH_HEADER_BYTE" | "MP3" | "WEBM_OPUS" | null | undefined;
  throwError?: boolean;
};

type STTGoogleConfig = {
  apiKey?: string;
  verbose?: boolean;
};

type STTGoogleParams = STTGoogleInputs & STTGoogleConfig;

type STTGoogleResult = GraphAINullableText

export const sttGoogleAgent: AgentFunction<STTGoogleParams, STTGoogleResult, STTGoogleInputs, STTGoogleConfig> = async ({ params, namedInputs }) => {
  const { stream, languageCode, sampleRateHertz, encoding, throwError } = { ...params, ...namedInputs };
  try {
    const speechClient = new SpeechClient();
    const audioBytes = stream instanceof Buffer ? stream.toString("base64") : stream;

    const audio = {
      content: audioBytes,
    };

    const config = {
      languageCode: languageCode || "ja-JP",
      sampleRateHertz: sampleRateHertz || 48000,
      encoding: encoding || "FLAC",
    };

    const request = {
      audio: audio,
      config: config,
    };

    // Detects speech in the audio file
    const [response] = await speechClient.recognize(request);
    const transcription = response.results
      ? response.results
          .map((result) => 
            result.alternatives && result.alternatives.length > 0
              ? result.alternatives[0].transcript
              : "error"
          )
          .join("\n")
      : "error";

    return {
      text: transcription,
    };
  } catch (e) {
    if (throwError) {
      console.error(e);
      throw new Error("STT Google Error");
    }
    return {
      error: e,
    };
  }
};

const sttGoogleAgentInfo: AgentFunctionInfo = {
  name: "sttGoogleAgent",
  agent: sttGoogleAgent,
  mock: sttGoogleAgent,
  samples: [
    {
      inputs: { stream: Buffer.from("dummy audio data") },
      params: {
        languageCode: "en-US",
        sampleRateHertz: 16000,
        encoding: "LINEAR16",
      },
      result: {
        text: "This is a sample transcription.",
      },
    },
  ],
  description: "Google Speech-to-Text agent",
  category: ["voice"],
  author: "Takuya Matsuda",
  repository: "https://github.com/your-repo/graphai-agents/",
  license: "MIT",
};

export default sttGoogleAgentInfo;

```
GTM権限がないページのカスタムJS変数の記述を調べる方法を探る

# ▼結論
`gtm.js?id=<containar_id>`のJavaScriptファイルの中身にて、`vtp_javascript`の文字列で検索すると見ることが出来る。
しかし、カスタムJavaScript変数が複数ある場合はどの変数の処理であるかは分からない。
(プレビューURLにて確認した際はどの変数にどのような処理が書かれているかが確認できるため、判別可能)
また、GTMにて設定されたそのままのスクリプトではなく、変数名や文字列が短縮されたり変換された形で表示されることがあるため処理内容を完全に把握することは難しいこともある

※`gtm.js?id=<containar_id>`の中身は検証ツールのSourcesタブの`www.googletagmanager.com`配下またはnetworkタブのリクエストを開くことで確認できる

# ▼背景
カスタムJS変数の記述がどうなっているかを調べる必要があった。しかし、GTM権限は別会社が持っているため設定を確認することが出来なかった。その中でカスタムJSの記述を調べる方法はないか模索した。

これが可能であれば、GTMで計測設定を行っている各ウェブサイトがどのようなカスタムJS変数を作成しているのかを調べること出来るということになる。

# ▼調査

## 事前準備
以下スクリプトのカスタムJS変数をクリックイベントのイベントパラメータとして設定した。
このイベントは要素Ａのクリックをトリガーとしていると想定する。

```javascript
function() {
  return document.title;
}
```
このJavaScriptの記述をどうにか見つけることが出来ないかを探る

## 仮説➀クリックイベントのイベントリスナーとして設定されているのではないか？

この仮説を元に、要素Ａに貼られているイベントリスナーを調べる。
以下のようになった。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2998651/f4da28c7-f494-42e8-a4ed-87058df37fd8.png)

これは要素Aをクリックすると`gtm.js?id=<containar_id>`ファイルにて記述している関数が呼ばれていることを表す。

参照先に移動すると以下のようになった。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2998651/ab9ace7f-c8c2-4c6c-b6f6-0427f6f7bd58.png)

選択している箇所の`function(p)`が呼ばれているようである。
これではよく分からない...

しかし、`gtm.js?id=<containar_id>`ファイル内にカスタムJSも記述されてる可能性が高そうだ

## 仮説➁`gtm.js?id=<containar_id>`ファイル内をJSの処理にて文字列検索する

今回のケースではカスタムJSに書いた処理が分かっている。そのため、文字列検索を試みた。
検索文字列`return document.title`

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2998651/4a6fe31c-103a-46aa-8c77-c77eb82685a3.png)

無事見つけることが出来た。

## 分かったこと
- カスタムJavaScript変数に記述した処理は`gtm.js?id=<containar_id>`ファイルに記載されている
- `vtp_javascript`というキーの値としてカスタムJSの処理が格納されている

# ▼補足
- プレビューURLを検証ツールで調べるとデバッグ用のgtm.js..というJavaScriptファイルが存在する
    - このファイル内では変数名も表示される

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2998651/9d0c8d22-f870-4b06-ba79-bccaf9a77b03.png)

- カスタムJSの処理の中で`const hogehoge = "fugaguga"`などと記述していると短縮されて表示される
ex)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2998651/eeb17d6b-3cd0-47cc-b014-23eba9c3f6a3.png)
処理内容は無視していただきたい。
変数名がaなどに変換されたり、while分がfor文に変換されたりとGTMにて記述した処理とは異なる形で記載されている。
変数名や文字列、コメントアウトのデータ量を削減かつ情報隠蔽が意図されていると推察する。

※カスタムHTMLタグも同様
HP作成備忘録：ホームページのロゴとテキストを横並びに！HTML×CSSの基本テクニック

## はじめに

社労士事務所などのホームページを制作していると、「ロゴ画像とタイトル文字（事務所名）を横に並べたい」というシンプルながらも重要なデザイン調整が必要になることがあります。

:::note info
**個人の備忘録程度の走り書きとなっておりますが、温かい目で見守っていただければ幸いです。**
:::

今回は、実際に「ホンダ社労士事務所」のトップページを例に、ロゴとタイトルを自然に横並びに整える方法をご紹介します。

---

## 困っていたこと

HTML上では以下のようにロゴ画像とタイトルが並べられていますが、実際の表示では縦に並んでしまっている状態でした。

```html
<header>
  <img src="images/logo.png" alt="ロゴ" style="height: 50px; margin-right: 10px;">
  <h1><a href="index.html">ホンダ社労士事務所</a></h1>
</header>
```

これは、`img` と `h1` がブロック要素として縦に積まれてしまうためです。

**実際のフロント画面について**

![Screenshot 2025-03-22 at 22.23.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/8cfa1455-1d9e-4684-87a7-67edfc996892.png)

---

## 解決方法：Flexboxで横並びにする

画像とタイトルを横並びにするには、2つの要素をひとつの `div` でまとめ、Flexbox を使うのが一般的です。

### 実際のHTMLコード（修正済み）
```html
<header>
  <div class="header-title">
    <img src="images/logo.png" alt="ロゴ" style="height: 50px; margin-right: 10px;">
    <h1 style="margin: 0;"><a href="index.html">ホンダ社労士事務所</a></h1>
  </div>
  <nav>
    <a href="index.html">HOME</a>
    <a href="greeting.html">代表挨拶</a>
    <a href="office.html">事務所案内</a>
    <a href="services.html">サービス案内</a>
    <a href="pricing.html">料金案内</a>
    <a href="contact.html">お問い合わせ</a>
    <a href="support-a.html">就労支援A型</a>
  </nav>
</header>
```

### 実際のCSSコード（style.cssなどに追加）
```css
.header-title {
  display: flex;
  align-items: center;
  justify-content: center; /* 必要に応じて中央揃え */
}
```

このように実装することで、見た目にも整った横並びが実現できます。

このようにすることで、`img` と `h1` が横に並び、ロゴの左に事務所名が自然に表示されます。

また、`align-items: center;` を使うことで、ロゴとテキストの縦方向の中央揃えも実現できます。

---

## まとめ

- ブロック要素はそのままだと縦に並ぶ → Flexbox を使って横並びに
- ロゴ画像とタイトルをまとめるラッパー要素を用意する
- `display: flex` と `align-items: center` を指定すれば整ったレイアウトに

このように、少しのHTMLとCSSの工夫で見た目を大きく改善できるので、試してみてください！
［Rails］has_many関連付けを用いた際にNoMethodErrorが出る原因

## はじめに
railsでデータベースのリレーションを行うためにhas_many、belongs_toを用いたところ「NoMethodError」が発生したため備忘録として記録します。
<br>

## エラー発生部分

```ruby:movie.rb
class Movie < ApplicationRecord
    has_many :schedule
end
```

```ruby:schedule.rb
class Schedule < ApplicationRecord
    belongs_to :movie
end
```

MovieテーブルとScheduleテーブルを1対多(1つの映画に複数の上映スケジュールがある)で対応させるためにhas_many、belongs_toで対応させてテストしたところ、「movie.schedules」の部分で以下のエラーが発生しました。

```
NoMethodError: undefined method `schedules' for
```

<br>

## 原因
has_many関連付けの相手となるモデルの名前が**複数形になっていなかった**ことが原因でした。

今回の場合、Movieモデルの相手となるScheduleモデルの表記方法を以下のようにすることで、scheduleメソッドを問題なく呼び出せるようになりました。

```ruby:movie.rb
class Movie < ApplicationRecord
    has_many :schedules
end
```

<br>
なお、belongs_to関連付けで指定するモデル名は必ず「単数系」にする必要があります。

**「Railsは関連付けの名前から自動的にモデルのクラス名を推測するため、関連付け名が複数形になっていると推測されるクラス名も複数形の誤った形になってしまう」**
ことが理由のようです。
<br>
参考記事：[Railsガイド Active Record の関連付け](https://railsguides.jp/association_basics.html)


## まとめ
belongs_to関連付けで指定するモデルは「単数形」、has_many関連付けで指定するモデルは「複数形」にすることを確認する必要があると理解することができました。
vcpkgのインストール

vcpkgはWindowsの(あんまり便利じゃない)パッケージ管理プログラムです。
## コマンド
``C:\``に移動し管理者権限で以下のコマンドを実行する。
```.bat
git clone https://github.com/microsoft/vcpkg
cd c:\vcpkg
git pull
.\bootstrap-vcpkg.bat
cd c:\
c:\vcpkg\vcpkg update
c:\vcpkg\vcpkg integrate install 
```
## 環境変数
システムの環境変数に以下の環境変数を追加してください。
| 環境変数名             | パス                                                |
|------------------------|----------------------------------------------------|
| VCPKG_ROOT             | c:\vcpkg                                           |
| VCPKG_DEFAULT_TRIPLET  | x64-windows                                        |
| CMAKE_TOOLCHAIN_FILE   | c:/vcpkg/scripts/buildsystems/vcpkg.cmake          |
| LIB                    | c:/vcpkg/installed/x64-windows/lib                  |
| INCLUDE                | c:/vcpkg/installed/x64-windows/include              |
| Path                   | c:/vcpkg                                           |
| Path                   | c:/vcpkg/installed/x64-windows/bin                  |

```.bat
powershell -command "[System.Environment]::SetEnvironmentVariable(\"VCPKG_ROOT\", \"c:\vcpkg\", \"Machine\")"
powershell -command "[System.Environment]::SetEnvironmentVariable(\"VCPKG_DEFAULT_TRIPLET\", \"x64-windows\", \"Machine\")"
powershell -command "[System.Environment]::SetEnvironmentVariable(\"CMAKE_TOOLCHAIN_FILE\", \"c:/vcpkg/scripts/buildsystems/vcpkg.cmake\", \"Machine\")"
powershell -command "$oldpath = [System.Environment]::GetEnvironmentVariable(\"LIB\", \"Machine\"); $oldpath += \";c:\vcpkg\installed\x64-windows\lib\"; [System.Environment]::SetEnvironmentVariable(\"LIB\", $oldpath, \"Machine\")"
powershell -command "$oldpath = [System.Environment]::GetEnvironmentVariable(\"INCLUDE\", \"Machine\"); $oldpath += \";c:\vcpkg\installed\x64-windows\include\"; [System.Environment]::SetEnvironmentVariable(\"INCLUDE\", $oldpath, \"Machine\")"
powershell -command "$oldpath = [System.Environment]::GetEnvironmentVariable(\"Path\", \"Machine\"); $oldpath += \";c:\vcpkg\"; [System.Environment]::SetEnvironmentVariable(\"Path\", $oldpath, \"Machine\")"
powershell -command "$oldpath = [System.Environment]::GetEnvironmentVariable(\"Path\", \"Machine\"); $oldpath += \";c:\vcpkg\installed\x64-windows\bin\"; [System.Environment]::SetEnvironmentVariable(\"Path\", $oldpath, \"Machine\")"
```
以上、お疲れ様でしたー
Unity - インスペクターに変数を表示したい！~publicと[SerializeField]について~

### 変数をインスペクターに表示する、魔法ような、神のような構文
え？インスペクターで変数を表示できるようにしたい？分かります。めっちゃ分かります。変数って、何かと便利ですもんね。
そんな変数をインスペクターに表示させる構文をお教えしましょう。
**ズバリ、`public`です。**
例を交えて説明します。
### ＠publicを付けたら何かと便利な件
```c#:Test.cs
using System;
using System.Collections.Generic;
using UnityEngine;

public class TestScript : MonoBehaviour
{
    public int Int;
    public float Float;
    public double Double;
    public bool Bool;
    public char Char;
    public string String;
    public List<int> list;
    public int[] Array = new int[] {1, 2};
}
```
:::note warn
注意
List型変数と配列型変数(上記のスクリプトでは`int[]`)を使うときは、必ず
```c#
using System;
using System.Collections.Generic;
```
を記述しましょう。抜けていると、エラーが発生してうまく実行できません。
:::

こんな処理を書いたとします。
これを実行してーの、表示されてーの...実行結果はこうなります。
![スクリーンショット 2025-03-22 191300.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4042593/dbd62cc5-4894-4531-94d7-699dbedcdb18.png)
`int[]`はなぜか表示されていませんが、とにかく、実行結果はこんな感じになります。(ListはInspector上で追加しています。)

秘密は、先ほども紹介した通り、`public`にあります。
このスクリプト、他のクラスにも変数を公開できるのと同時に、Inspectorにも表示されるという優れものなのです。
### `public`と何が違う？`[SerializeField]`について
`public`と似た処理の中に、`[SerializeField]`というものがあります。記述方法は、`public`を`[SerializeField]`に変えるだけです。

この`[SerializeField]`は、こんな時に使えます
・Inspector上に情報を表示したい時
・他のスクリプトに意図せずに値を渡して変更されて欲しくない時

この処理は、2人以上でプロジェクトを作成しているときに重宝します。
例えば、、、
>AさんとBさんは一緒にプロジェクトを作成しています。
>ただし、AさんとBさんは別々のスクリプトを担当しています。
>Aさんは、Inspector上に情報を表示したいと思い、以下のような処理を書きました；
>```c#
>public float Object_Hearth;
>```
>実は、この変数`Object_Hearth`はAさんは公開する意図はなかったのですが、Bさんは「`Object_Hearth`は使えるな」と考え、担当しているスクリプトに組み込んでしまいました。
>結果として、プロジェクトがおかしなことになりましたとさ。

こんな悲しい結果を防ぐためにも、`[SerializeField]`は重宝するのです[^1]。
ちなみに、Aさんは、このことを知ってこんな処理に訂正しました。
```c#
[SerializeField] private float Object_Hearth;
//privateと表記しておくことで、このオブジェクトを使ってほしくないことや、使えないことを明示できます。
```

### まとめ
今回は、`public`と`[SerializeField]`について解説しました。

`public`は、インスペクターに変数を表示したいときや、同時に変数を別のスクリプトで使えるようにしたいときに有効です。
`[SerializeField]`は、インスペクターに変数を表示したいけど、変数を別のスクリプトで使えるように**したくない**ときに有効です。
***
質問があればいつでもどうぞ！できる範囲でお答えします。
[^1]:参考サイト：[【初心者Unity】[SerializeField]ってなに？ | TECH PROjin](https://tech.pjin.jp/blog/2021/12/23/unity-serializefield "")
備忘：既存のコードをGitHubリポジトリにアップする

## GitHubにコードファイルをアップロードする手順

### 1. GitHubでリポジトリを作成

1. **GitHubにログイン**: GitHubにアクセスし、ログインします。
2. **リポジトリの作成**: 右上にある「+」アイコンをクリックし、「New repository」を選択します。
3. **リポジトリ名と説明の入力**: リポジトリ名を入力し、必要に応じて説明を追加します。
4. **公開設定の選択**: 公開設定（Public/Private）を選択します。
5. **リポジトリの作成**: 「Create repository」ボタンをクリックしてリポジトリを作成します。

### 2. ローカル環境の準備

1. **コードファイルのあるディレクトリに移動**: コードファイルが存在するローカルディレクトリに移動します。
2. **ターミナルまたはGit Bashを開く**: ターミナルまたはGit Bashを開きます。

### 3. Gitの初期化とファイルの追加

1. **Gitリポジトリの初期化**:

```bash
git init
```

2. **ファイルのステージング**:

```bash
git add .
```

3. **コミットの作成**:

```bash
git commit -m "Initial commit"
```


### 4. リモートリポジトリの設定

1. **GitHubリポジトリのURLをコピー**: GitHubリポジトリのURLをコピーします。
2. **リモートリポジトリの追加**:

```bash
git remote add origin <GitHubリポジトリのURL>
```


### 5. GitHubへのプッシュ

1. **GitHubへのプッシュ**:

```bash
git push -u origin main
```


これらの手順を実行すると、ローカルのコードファイルがGitHubリポジトリにアップロードされます。

**注意**: 機密情報（パスワードやAPIキーなど）を含むファイルは絶対にGitHubにプッシュしないようにしてください。
AWSが展開するフロントエンドWebとモバイルカテゴリのサービスの一覧

## はじめに
AWSが展開するフロントエンドWebとモバイルカテゴリのサービスの一覧についてまとめてみました。

## フロントエンドWebとモバイルカテゴリ
　モバイル向けのアプリケーションやバックエンド処理を開発・運用をサポートするためのサービス群。

## AWS Amplify
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387980/bb4f95c3-a8d8-49fd-a6ff-266cdda949d7.png)
モバイルアプリケーションのバックエンドサービスをサーバーレスで自動セットアップするライブラリ。モバイル向け統合バックエンドサービスだった「AWS Mobile Hub」も機能統合された。

## AWS AppSync
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387980/c61afcb8-bf1b-457c-bd09-06be458f7cd9.png)
GraphQLをベースとしたフルマネージドアプリケーションサービス。

## AWS Device Farm
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387980/a967907c-18e3-44ea-b767-7cc722a77039.png)
AWSクラウド上でデバイスの実機を使用してモバイルおよびWebアプリケーションのテストを行うサービス。

## Amazon Location Service
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387980/86d92c22-df50-43aa-950f-ff39cf3311e8.png)
デバイスのGPS位置情報と連携して、イベント駆動でLambdaやEventBridge、SNSなどのAWSサービスを実行出来るサービス。



## おわりに
ここまで読んでいただきありがとうございます！

## 参考文献
・AWSの基本・仕組み・重要用語が全部わかる教科書 (見るだけ図解) 単行本（ソフトカバー） – 2022/8/23
川畑光平 (著), 菊地貴彰 (著), 真中俊輝 (著)
p.61
AWSが展開する移行と転送カテゴリのサービスの一覧

## はじめに
AWSが展開するIoTカテゴリのサービスの一覧についてまとめてみました。

## 移行と転送カテゴリ
　オンプレミスシステムやレガシーなクラウドサービスを使った環境からモダンなAWSプラットフォームへ移行するためのサービス群。レガシーマイグレーションは近年、企業の重要な課題に位置づけられている。どのようなサービスが利用可能か押さえておきたい。

## AWS Application Discovery Service
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387980/7761f827-a8ed-4699-ae73-c452cf70af58.png)
クラウドへの移行に向けた既存ITシステムのデータ収集サービス。

## AWS Application Migration Service
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387980/932dcf29-480c-4fa0-aa17-ae6ba81e9898.png)
クラウドへアプリケーションリフト＆シフトを実現するためのサービス。2019年にAWSが買収した、オンプレミスサーバにエージェントをインストールすることで、アプリケーション環境をAWSクラウドに移行させる「CloudEndure Migration」と同等の機能をマネージメントコンソール上から実現する。

## AWS Database Migration Service
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387980/2eed51d6-3573-4020-afa3-e131e4accccb.png)
オンプレミスやEC2上に構築したデータベースなどからのAWSのマネージドデータストア、Kinesis、MSKなどへデータ移行するサービス。

## AWS DataSync
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387980/d6f7fd45-07ab-44ef-b1f6-6f6ac1a78511.png)
オンプレミスストレージとS3やEFS間のデータの移動を自動化するデータ転送サービス。

## AWS Mainframe Modernization
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387980/9aeb3fa7-73fe-41ab-8837-de67eeadcb2d.png)
メインフレームの環境やレガシーアプリケーションをリファクタリングし、モダンな言語へ変換するサービスおよび開発・テストツール群。

## AWS Migration Hub
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387980/67b1d1ad-eba9-4c59-813d-ec9ca77237ee.png)
移行サービスであるApplication Discovery ServiceやDatabase Migration Service、Server Migration Serviceに関する移行サマリダッシュボードを統合したサービス。

## AWS Schema Conversion Tool
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387980/92ca9e02-b8c2-4d27-8733-a566c442f277.png)
ソースとなるデータベースのスキーマ、ビュー、ストアドプロシージャなどをマネージドデータベースへ移行するサービス。

## AWS Server Migration Service
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387980/cc9c842b-5902-41bb-a1bc-c9c4b5d64bfb.png)
VMWareやHyper-V、Azure上に構築したマシンイメージをAWSへ移行するサービス。

## AWS Snow Family
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387980/73d946f8-146d-4a62-a54f-f41ca20d2ed2.png)
AWSが高性能のストレージを貸し出し、オンプレミスのデータをS3へ物理的にデータ移送・転送するサービス。

## AWS Transfer Family
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387980/00337a61-cf69-4012-b4e3-7df31e06ce1e.png)
SFTP、FTP、FTPSプロトコルを用いて、S3との間で直接ファイル転送を行うサービス。

 


## おわりに
ここまで読んでいただきありがとうございます！

## 参考文献
・AWSの基本・仕組み・重要用語が全部わかる教科書 (見るだけ図解) 単行本（ソフトカバー） – 2022/8/23
川畑光平 (著), 菊地貴彰 (著), 真中俊輝 (著)
p.60-61
LaravelでAPI使用時にセッションを有効にする方法

# はじめに
今回はLaravel11でセッションを有効にする方法について記載します。

## 前提条件
PHP 8.3
Laravel 11.4

## 設定について

Laravel11にはkernel.phpファイルがないので、bootstrapディレクトリ内のapp.phpファイルにセッションを有効化するコードを記載していきます。

```php:bootstrap/app.php
<?php

use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Foundation\Configuration\Middleware;

return Application::configure(basePath: dirname(__DIR__))
    ->withRouting(
        web: __DIR__.'/../routes/web.php',
        api: __DIR__.'/../routes/api.php',
        commands: __DIR__.'/../routes/console.php',
        health: '/up',
    )
    ->withMiddleware(function (Middleware $middleware) {
        $middleware->group('api', [
            // セッションに関するミドルウェア
            \Illuminate\Cookie\Middleware\EncryptCookies::class,
            \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
            \Illuminate\Session\Middleware\StartSession::class,
            \Illuminate\View\Middleware\ShareErrorsFromSession::class,
        ]);
    })
    ->withExceptions(function (Exceptions $exceptions) {
        //
    })->create();
```

# 参考ページ
公式リファレンスにはセッションの有効にする方法の記載はなかったので色んな記事を参考にしました。
また、ミドルウェアの設定方法については下記を参考にしました。
https://readouble.com/laravel/11.x/ja/middleware.html
パスワードをConvertFrom-SecureStringで暗号化

# 初めに
最近よくある相談事に「認証情報やパスワードをスクリプトに入れたくないのだけどどうすればいい？」があります。

Azure なら KeyVault を使ったり、マネージドIDを使ってそもそもパスワードを使わない運用にしたりします。

では端末だけで実行するならどうするか、というお話です。

:::note info
この方法の特徴
* 暗号化を行ったコンピューター上で、その暗号化を実行したユーザーだけが復号できます
* 異なる端末／ユーザーに配布する場合、そのユーザー・環境ごとに暗号化したファイルや文字列が必要です
:::

# SecureStringを使う
暗号化した文字列を Read-Host と ConvertFrom-SecureString を使って作ることができます。

```powershell:認証情報を暗号化するスクリプト.ps1
# 出力先
$OutFilePath = "c:\temp\encriptText.txt"

# 暗号化文字列を作る(入力する場合)
$SecureString = Read-Host "EnterPassword" -AsSecureString
# テキストファイルを暗号化する場合
# Get-Content $InputFilePath | ConvertTo-SecureString  -AsPlainText -Force

# パスワードをDPAPIで暗号化
$EncryptedString = ConvertFrom-SecureString -SecureString $SecureString 

# ファイルに書き出し
$EncryptedString | Out-File $OutFilePath
```

```powershell:認証情報を使うスクリプト.ps1
# 暗号文
$EncryptedFilePath = "c:\temp\encriptText.txt"

$EncryptedString = Get-Content -LiteralPath $EncryptedFilePath
$SecureString    = ConvertTo-SecureString -String $EncryptedString

# コード内で平文が必要ならこれで変換
$BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($secureString)

$plainText = [System.Runtime.InteropServices.Marshal]::PtrToStringBSTR($BSTR)
```
結果：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2679378/9e59ebf2-8349-1cf7-eb66-8592a49c50d2.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2679378/53710e32-bacd-f992-0eda-77b713371b1a.png)

:::note warn
共用PCや本番環境で 
$SecureString = ConvertTo-SecureString 'hogehoge' -AsPlainText -Force
とかのコマンドを実行しないようにしましょう。
この例だと平文 'hogehoge' が履歴に残ります。 
:::

これで暗号化した文字列は、これを実行したユーザーがこのコンピューター上で実行するときに限り展開できるので、スクリプトと暗号化文字列を持ち出されても多少は安心。この文字列を別ファイルにしたり、ヒアストリングでスクリプトに埋め込んでください。

[ConvertFrom-SecureString](https://learn.microsoft.com/ja-jp/powershell/module/microsoft.powershell.security/convertfrom-securestring?view=powershell-7.4)
>  キーを指定しない場合には、Windows データ保護 API (DPAPI) が使用されて標準文字列の表現が暗号化されます。

[方法: データ保護の使用](https://learn.microsoft.com/ja-jp/dotnet/standard/security/how-to-use-data-protection)
> .NET では、データ保護 API (DPAPI) へのアクセスを提供しています。これを使用すると、現在のユーザー アカウントまたはコンピューターからの情報を使用してデータを暗号化できます。

# ユーザーと実行ユーザーを分離する
さらに強度を上げるならタスクスケジューラーを使います。

こちらのコラム紹介しているような方法で、スクリプトの恩恵を受けるユーザーと、スクリプトを実行するジョブ用のユーザアカウントを分離します。

[PowerShellコラム：別のユーザーで処理を実行する 1](https://www.intellilink.co.jp/column/ms/2022/041400.aspx)

[PowerShellコラム：別のユーザーで処理を実行する 2
](https://www.intellilink.co.jp/column/ms/2022/063000.aspx)

コラムの1は、エンドユーザーがタスクスケジューラーを叩きます。
タスクスケジューラーは、暗号化に使用したアカウントの権限でスクリプトを実行します。
ユーザーアカウントはタスクスケジューラーのタスクを実行する権限が必要ですが、設定が容易です。

コラムの2は、エンドユーザーがイベントログをスクリプト経由で発行します。
タスクスケジューラーは発行されたイベントをトリガーとして、暗号化に使用したアカウントを用いて目的のスクリプトを実行します。

設定がやや煩雑になりますが、ユーザーはイベントログの発行する権限があれば実行できます。

# 終わりに
Powershell で簡単にパスワード等を暗号化する方法を紹介しました。

ちなみに今回はキーを使用しない方法を選びましたが、 ConvertFrom-SecureString は任意のキー(バイト配列)を使用することもできます。

こちらの方式であれば複数のユーザーや端末間でも共有が可能です。パスワードを暗号化するためのキーを平文で手元に残しておく必要があるので採用しませんでしたが、単に難読化したい場合はこちらもご検討ください。

スクリプト内での認証情報の保護やパスワードの暗号化の参考になれば幸いです。
【EKS】Loki＋Promtail＋Grafanaでログ収集してみる

# 背景
背景①
プロジェクトにて、EKSを活用したアプリケーション構築を経験しており、ログ収集・監視ツールとしてDynatraceを使っている。
Dynatraceではコンソール上からPodのログをWeb GUIベースで確認ができるが、正直無料でどこまでログ可視化を実施することができるのかがわかっていない。
Dynatraceと比較して、無料であれば出来ること・出来ないことなどをまとめていきたい。

背景②
個人開発の一環で勉強としてEKSを使って構築しているが、アプリケーションログの見方が「kubectl logs」のコマンドだけであり、文言やステータスベースでのフィルタリングが出来ずに困っている。
# 実装

loki-stackをデプロイする
```
kubectl create ns monitoring
helm install -n monitoring grafana/loki-stack --generate-name --set grafana.enabled=true
```
以下が表示される
```
kubectl get svc -n monitoring
NAME                               TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
loki-stack-1742550019              ClusterIP   IPアドレス   <none>        3100/TCP   30s
loki-stack-1742550019-grafana      ClusterIP   IPアドレス   <none>        80/TCP     30s
loki-stack-1742550019-headless     ClusterIP   None             <none>        3100/TCP   30s
loki-stack-1742550019-memberlist   ClusterIP   None             <none>        7946/TCP   30s
```
LoadBalancerやClusterIPでの指定も可能だが、今回は無料で実施したかったため、NodePortを利用した実装に変更
※以下コマンドを実行し、typeをClusterIP→NodePortへ変更
```
kubectl edit svc -n monitoring loki-stack-1742550019-grafana
```
Grafanaへ接続できるようになりました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3552177/75acf9c5-7bcb-49a2-91ac-e567b239f19f.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3552177/174a5e49-097f-4d95-9093-d408d54db712.png)

# Dynatraceでしか出来ないこと・Grafanaでも出来ること
単純に触ってみての感想を書こうと思います。
#### Podログの収集、フィルタリング
どちらでも出来ると感じました。
特にフィルタリングに関してはデフォルトでNamespaceやContainer単位でのログ収集が可能で、初期設定でこれらが実装されるのはとても分かりやすいなと感じました。
#### ステータスレベルでのフィルタリング
知識不足の可能性はありますが、Dynatraceでしかできないと感じました。
Dynatraceではステータスレベルでフィルタリングが可能で、このフィルタリング設定があればなおGrafanaでも分かりやすくなるだろうなと感じました。
しかしGrafana側では、ログのテキスト部分一致が可能のため「Error」が入っているログのみ収集が可能です。この機能によってステータスレベルでのフィルタリングに近づけそうだなと感じました。
#### 過去のpodのログ収集
DynatraceはエージェントをデプロイしてSaaSへログを転送している一方、LokiはEKS Nodeの/var/logフォルダにあるPodログを直接見に行っているため、Nodeのライフサイクルにより過去のPodログは見ることができないと考えました。
# 実施してみて
今回初めてGrafanaを自分でデプロイしたため、まだ機能を完全に使いこなせていないだろうなと感じました。
次回はChatGPTやAWS Bedrockなどと組み合わせてAI Opsなども経験してみたいと考えました
DiscordBotをおためしで作ってみた！ 

# Node.jsでDiscord Botを作ってみた！

こんにちは！今回は、Node.jsを使ってDiscord Botを作成した経験を共有します。

## 使用した環境

Node.js: v22.14.0

エディタ: Visual Studio Code

拡張機能: Node.js Modules

## 苦労したことと解決方法

#### Node.jsとVisual Studio Codeをつなげてコードを試すまでの環境構築

最初のハードルは、Node.jsとVSCodeを正しく連携させ、コードを試せる環境を構築することでした。設定ミスがあるとスクリプトが正常に動かず、何度も試行錯誤しました。

### 解決策:

環境構築はトライ＆エラーの繰り返しで、正しく動作するまで試しました。

設定ミスでWindowsが正常に動作しなくなる可能性がものもあったので、仮想環境を構築して安全に環境を試すのも有効だと考えました。

#### config.jsonとdeploy-commands.jsのTypeError

スクリプトの実行時にconfig.jsonやdeploy-commands.jsでTypeErrorが発生し、思うように動きませんでした。

### 解決策:

TypeErrorの原因を調査したところ、Path指定のミスが原因でした。

正しいパスを確認し、適切な設定を行うことで解決しました。

# 今後の展望

現在、ValorantのVCT（Valorant Champions Tour）が始まったので、そのスケジュールを自動で通知してくれるBotを作成したいと考えています。リアルタイムで試合情報を取得し、Discordで知らせるBotを目指して開発を進めていきます！

今後も学んだことを共有していくので、よろしくお願いします！

## 参考文献
https://www.geeklibrary.jp/counter-attack/discord-js-bot/

https://note.com/exteoi/n/nf1c37cb26c41
【NetworkFirewall】非対称ルーティングの発生と解消法

きっちり構成固めて作った環境で、いざVPNでEC2へアクセスした時、「あれっ接続できないぞ」となった時の絶望を感じたことはありますか？
しかもつながったり繋がらなかったり...
そんな状況、もしかしたら「非対称ルーティング」かもしれません。
（僕はプロジェクトに入って初めてこのワードを知りました！）

# 当時の構成
**パブリックサブネット**
・エンドポイント層
　　VPC Endpoint、Nat Gateway、VPN Endpoint配置用
  　※NatGatewayを介した通信はアウトバウンド経由でのアクセスを遮断
・トランジットゲートウェイ層
　　社内NWと接続するTransit GatewayアタッチメントのENI配置用
**プライベートサブネット**
・Firewall層
　　Firewallエンドポイント配置用
・アプリケーション層
　　動作基盤のEKS WorkerNode配置用
・データベース層
　　RDS配置用
・マネジメント層
　　踏み台EC2サーバ配置用
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3552177/08e6e566-b306-4bc9-91cf-2c9e6bf9f40e.png)


# 発生した事象
VPN Endpointから踏み台サーバへリモートデスクトップ接続した際に、接続できる時と接続できない事象が発生。
# 原因
NetworkFirewallの行き・戻りの通信が異なることで、非対称ルーティングが発生してしまっていた。
※NetworkFirewallが非対称ルーティングをサポートしていないという公式ドキュメントは↓に記載

https://docs.aws.amazon.com/ja_jp/network-firewall/latest/developerguide/asymmetric-routing.html

下図に記載の通り、VPN経由でManagement層にあるEC2サーバへアクセスするためには、同じサブネットにあるFirewallEndpointを経由しなければならない。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3552177/492d03e4-17cd-4bc8-a6df-891ce08c2928.png)

# 解消法
エンドポイント層サブネットを、インターネット通信の発生有無で分割。
・Natゲートウェイ用サブネット（Nat層）
→インターネット経由するため、Firewallを必ず経由するように設計。
VPN Endpoint/VPC Endpoint用サブネット（Endpoint層）
→内部通信でFirewallエンドポイントを経由する必要がないため、Firewallを経由しないように設計。
URLを保存したjsonファイルを使って、 自動検索

<h4>jsonファイル書き方</h4>

```ruby:
{
  "url": [
    "https://www.example1.com",
    "https://www.example2.com",
    "https://www.example3.com",
    "https://www.example4.com"
  ]
}
```


<br>

```ruby:
import json
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.firefox.service import Service
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.firefox.options import Options
from bs4 import BeautifulSoup

# 1. JSONファイルを読み込む
json_file_path = 'data.json'
with open(json_file_path, 'r', encoding='utf-8') as file:
    data = json.load(file)

# 2. Firefoxのオプション設定（ヘッドレスモードなど）
options = Options()
options.headless = False  # ブラウザを画面に表示する場合はFalseに設定

# 3. GeckoDriverのパスを指定して、SeleniumでFirefoxブラウザを起動
geckodriver_path = "/path/to/geckodriver"  # GeckoDriverのパスを指定してください
service = Service(geckodriver_path)

driver = webdriver.Firefox(service=service, options=options)

# 4. JSONデータを使ってDuckDuckGoで検索
for record in data:
    company_name = record["会社名"]
    search_url = f"https://duckduckgo.com/?q={company_name}"  # DuckDuckGoで検索

    driver.get(search_url)
    time.sleep(2)  # ページが読み込まれるのを待つ

    # 5. BeautifulSoupでページ内容を解析
    soup = BeautifulSoup(driver.page_source, 'html.parser')
    
    # 例えば、検索結果のリンクを取得
    results = soup.find_all('a', {'class': 'result__a'})  # DuckDuckGoの検索結果リンク
    

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

```