OmniAICreator/Qiita-1.07M huggingface dataset:
辞書検索をスマート化する　Map.get() ?? -1

Paizaの「paiza商店の商品価格」問題を解いたときの学び💡
`Map`って、こんなに使いやすかったんだ…！

## <br>🧾 問題概要：paiza商店でお買い物

- N個の商品（名前と価格）が与えられる
- M個の商品名が書かれた「お買い物リスト」が与えられる
- 各商品について、商店にあれば価格を、なければ -1 を出力する

<br> 入力例:
```
3 4
eraser 50
pencil 30
book 100
book
eraser
pencil
margaret
```
出力例:
```
100
50
30
-1
```

<br>

https://paiza.jp/works/mondai/data_structure/data_structure__dict_step4


## <br>△NGかも例（注意）
```js
priceMap.set(productName, price); // ❌ 価格が文字列のまま
```
このままだと「計算したいとき」に困る！
例えば合計金額出すときに '100' + 50 で 150 じゃなくて 10050 になる（爆）
なので、ちゃんと `Number()` で数値変換が必要。
```js
priceMap.set(productName, Number(price)); // ⭕️安全！
```

## <br>✅?? を使った方がシンプル！
```js
priceMap.has(item) ? priceMap.get(item) : -1; // ⛔ 
priceMap.get(item) ?? -1;                     // ⭕ 短くて読みやすい
```

`.get()` は見つからないと `undefined` を返すから、`??` と組み合わせるだけでOK！


## <br>💻 コード全体（コメント付き）
```js
const rl = require("readline").createInterface({ input: process.stdin });
const lines = [];

// 標準入力を1行ずつ配列に格納
rl.on("line", (input) => {
  lines.push(input);
});

rl.on("close", () => {
  // 1行目: 商品数N、お買い物リスト数Mを数値に変換して取得
  const [N, M] = lines[0].split(" ").map(Number);

  // 商品名と価格を格納するMap（辞書）を作成
  const priceMap = new Map();

  // N個の商品をMapに登録（価格は数値に変換）
  for (let i = 1; i <= N; i++) {
    const [productName, price] = lines[i].split(" ");
    priceMap.set(productName, Number(price));
  }

  // お買い物リストの部分を取得（N+1行目〜末尾まで）
  const shoppingList = lines.slice(N + 1);

  // 各商品について、価格を取得（なければ -1）して配列に
  const results = shoppingList.map(item =>
    priceMap.get(item) ?? -1
  );

  // 結果をまとめて出力
  console.log(results.join('\n'));
});
```

### <br>🔍 技術メモ & まとめ
- `Map` はJSの辞書操作で適している。構文もシンプル。
- `.set()` 時に `Number(price)` を忘れるとバグのもと。
- `.has()` より `get() ??` の方がスッキリ書ける。
- 結果は `join('\n')` で一気に出力 → パフォーマンスも良き。

<br><br>  [僕の失敗談(´;ω;｀)と解決話！🚀](https://paizabeginner.wordpress.com/2025/04/19/paiza%e3%81%a7%e5%9f%ba%e6%9c%ac%e3%83%9e%e3%82%b9%e3%82%bf%e3%83%bc%ef%bc%9amap%e3%81%a7%e5%95%86%e5%93%81%e4%be%a1%e6%a0%bc%e3%82%92%e4%b8%80%e7%99%ba%e6%a4%9c%e7%b4%a2%ef%bc%81/)
アルゴリズムとデータ構造：深さ優先探索と幅優先探索

## 参考文献
大槻兼資 著, 問題解決力を鍛える！アルゴリズムとデータ構造, 講談社, 2020
## 深さ優先探索 (DFS: Depth-First Search)
### 深さ優先探索とは
一通りずつ探索する手法。
参考文献では、虫食い算（筆算の一部を空白にしその部分の解を求める問題）を例に挙げられていた。
### 利用されるアルゴリズムの例(ChatGPTより)
* 連結成分の探索
    →グラフ内の連結成分の探索
* トポロジカルソート
    →有向非巡回グラフ(DAG: )のノードの順序づけ
* 迷路の解法
    →スタートからゴールまでの経路探索
* 2部グラフ判定
    →グラフを2つのグループに分けられるかの探索
* 閉路検出
    →有向グラフや無向グラフにおけるサイクルの有無の探索
    

## 幅優先探索 (BFS: Breadth-First Search)
### 幅優先探索
一通りずつ探索するのではなく、全通り一斉に探索する探索手法。
参考文献では迷路の最短経路の探索が例に挙げられていた。
### 利用されるアルゴリズムの例
* 無向グラフにおける最短経路探索
    重みが全て1のグラフにおけるグラフ内の最短経路探索
* レベル順探索
    * 木構造において階層ごとに処理を階層ごとに処理
* パズルの最小手数探索
    その名の通り
* webクローラー
    深さを制限しながらwebのリンクを横に展開して探索する

## 結論
深さ優先探索：とりあえず問題を解く
幅優先探索：最短で解く方法を探す

このように解釈した。
podman + VSCode dev containerでエラー [Command not found 'podman']


## Command not found 'podman'

### 現象

https://zenn.dev/ackylarkham/articles/ab5ddc3dd9ba1e

上記記事を参考に環境構築していたところ、
開発コンテナーの部分でエラーが発生。

![Screenshot 2025-04-19 at 17.30.57.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3361273/2e2d2ebc-639e-490b-a675-828ca784ce75.jpeg)

設定でdockerコマンドに変わりpodmanを叩くようにしている。

```
{
    "dev.containers.dockerPath": "podman"
}
```

もちろんターミナルではpodmanは叩ける。

```
python-devenv $ podman --version
podman version 5.4.2
```

#### 開発環境

```
- M1 Mac
    - OS: 15.4.1 (24E263)
- Podman Desktop
    - Version 1.18.0 (1.18.0)
- Visual Studio Code
    - Version: 1.99.3 (Universal)
    - Commit: 17baf841131aa23349f217ca7c570c76ee87b957
```

### 解決策

podmanへのフルパスを指定すると直った。

```
python-devenv $ which podman
/opt/podman/bin/podman
```

```
{
    "dev.containers.dockerPath": "/opt/podman/bin/podman"
}
```

なんでやねんって感じ。
おうちサーバー構築報告：Docker on ProxmoxVE

## 能書き

[おうちサーバー構築報告：予告](https://qiita.com/katz_engineer/items/471408eda1d09507c451)からのおうちサーバー構築です。

### 前提

- [我が家のサーバーマシンに Proxmox VE をインストールしている](https://qiita.com/katz_engineer/items/ee594cab0300398131f7)
- [ProxmoxVE上に仮想マシンを作成、Ubuntu Server 24.04 LTS を入れている](https://qiita.com/katz_engineer/items/932640f6c209a4ffddbb)
- [おうちサーバー構築報告：AnsibleでProxmoxVEのゲストマシン4台それぞれ/etcをSubversion管理 - Qiita](https://qiita.com/katz_engineer/items/d46b60e6606563e75859)
    - Dockerのインストール先として仮想マシンを1台構築済（IPアドレスは`172.16.1.105`）
    - `/etc`をSubversion管理

### 目標

- Proxmox VE 上の仮想マシンに Docker をインストール
    - docker compose で`hello-world`を実行して動作確認

### 参考文献

今回の設定に必要な事前準備などは下記になります。

- [Docker確認 - おうちサーバー構築報告：仮想マシンとDocker on Proxmox VE with ZFS - Qiita](https://qiita.com/katz_engineer/items/932640f6c209a4ffddbb#docker%E7%A2%BA%E8%AA%8D)
- [おうちサーバー構築報告：Proxmox VE with ZFS - Qiita](https://qiita.com/katz_engineer/items/ee594cab0300398131f7)

Dockerインストール手順は下記記事を参照させていただきました。

- [Ubuntu24.04へDocker Engine 一式をインストール （Compose含む） - Qiita](https://qiita.com/kujiraza/items/00b9066c49ddfc718fd6)

また今回、`root`ユーザー以外でDockerを使う為のユーザーグループを設定します。

- [Manage Docker as a non-root user - Linux post-installation steps for Docker Engine - dockerdocs](https://docs.docker.com/engine/install/linux-postinstall/#manage-docker-as-a-non-root-user)

その他、エラーへの対応など。

- [Docker 一般ユーザーでのdockerコマンドの利用 - IT技術で仕事を減らしたい！](https://timesaving.hatenablog.com/entry/2022/06/25/150000)
- [最もシンプルな docker-compose.yml の hello-world - Qiita](https://qiita.com/KEINOS/items/43d9415e351d80f78c8b)

## インストール

まずはパッケージリストの更新。

```console
sudo apt update
```

依存パッケージをインストールします。

```console
sudo apt install ca-certificates curl
```

Dockerリポジトリの公開鍵をUbuntu推奨ディレクトリへ格納します。

```console
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
```

Dockerの公式リポジトリをシステムに追加します。

```console
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc]  https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" |  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
```

Docker Engineをインストールします。

```console
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
```

動作確認。

```console
docker --version
docker compose version
```

## Dockerグループ設定

`root`ユーザー以外でDockerを使う為のユーザーグループを設定します。

まず、`docker`グループが存在する事を確認します。

```console
grep docker /etc/group
```

存在しないなら`docker`グループを作成しましょう。もし既に存在していたらそのまま放置でOKです。

```console
sudo groupadd docker
```

ユーザーに`docker`グループを付加します。

```console
sudo usermod -aG docker $USER
```

そうしたら一旦ログアウトして、ログインしなおします。または次のコマンドを実行します。

```console
newgrp docker
```

`sudo`を付けずに`docker`できる筈です。

```console
docker run hello-world
```

[docker compose も一応確認](https://qiita.com/KEINOS/items/43d9415e351d80f78c8b)しておきましょう。

```console
cd
mkdir hello-world
cd hello-world
cat <<___ >compose.yaml
services:
  hello:
    image: hello-world:latest
___
docker compose up -d
docker compose logs
```

## 仕舞い

Ubuntuインストール時のdockerの指定は、snapからのインストールになり、コンテナの置き場所に制限が掛かるようです。こんなバッドノウハウがあるとは…悲しいですな。
異体字を標準文字に変換するPythonプログラム

歴史的な文書を扱っていると、人名や地名に異体字が頻繁に登場します（齋、髙、濵など）。検索やデータ処理の場面ではかなり厄介です。この記事では、そうした異体字を自動で標準的な文字に変換するプログラムを紹介します。

## なぜ作ったのか？
研究で歴史的なデータを扱っています。その際、人名が資料に含まれているか確認したり、地名から緯度経度を取得したり（APIを使う）する必要があります。しかし、異体字・旧字体が使われていると、検索や照合がうまくいきません。

旧字体を変換するツールはいくつか見つかりましたが、異体字に特化した変換ツールが見当たらなかったため、自分で作ることにしました。
旧字体っぽく見えるけど実は旧字体ではない異体字があります。私が実際に出会った例だと、「鉄」の異体字である「鐡」があります。これは、旧字体の「鐵」とも微妙に異なります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3813135/da866fb0-d2e2-427b-9e37-0078fb75ce29.png)
そのため、旧字体変換サイトでは変換できませんでした。
※ 厳密には旧字体も異体字の一種とされていますが、この記事では両者を区別しています。あしからず...

## 実装の概要
### 方針
- 異体字と標準形の対応表を取得
- それをもとに変換辞書を作成
- 文字列中の異体字を一括で置換する関数を作成

### 使用ライブラリ
```bash
pip install requests beautifulsoup4
```
これらのライブラリは以下の用途で使用します。
- `requests`：対応表のHTMLをダウンロード
- `BeautifulSoup`：HTMLから表のデータを抽出

### 対応表の取得
異体字の対応表は以下のものを使います。
[史料編纂所データベース異体字同定一覧](https://wwwap.hi.u-tokyo.ac.jp/ships/itaiji_list.jsp)

まずはHTMLページをダウンロードし、表の内容を抽出します。
```python
import requests
from bs4 import BeautifulSoup

# 史料編纂所データベース異体字同定一覧
url = "https://wwwap.hi.u-tokyo.ac.jp/ships/itaiji_list.jsp"

# HTMLをダウンロード
response = requests.get(url)
response.encoding = "utf-8"
html = response.text

# BeautifulSoupでパース
soup = BeautifulSoup(html, "lxml")

# <table>要素を探す
table = soup.find("table")

# 各行を抽出（ヘッダーをスキップ）
data = []
for row in table.find_all("tr")[1:]:
    cols = row.find_all(["td", "th"])
    cols = [col.get_text(strip=True) for col in cols]

    if len(cols) >= 2:
        standard = cols[1]
        variants = cols[2].split() if len(cols) > 2 else []
        data.append((standard, variants))

# 確認用に数件出力
for s, vs in data[:5]:
    print(f"{s} ← {' '.join(vs)}")
    
# 出力例：
# 亜 ← 亞
# 唖 ← 啞 瘂
# 悪 ← 惡
# 芦 ← 蘆
# 鯵 ← 鰺
```

### 対応表から変換辞書を作成
異体字 → 標準形 の辞書を生成します。
```python
# 変換辞書を作成
conversion_dict = {}
for standard, variants in data:
	for variant in variants:
		conversion_dict[variant] = standard

print(conversion_dict)
# 出力例：
# {'亞': '亜', '啞': '唖', '瘂': '唖', '惡': '悪', ...}
```


### 文字列の一括変換関数
異体字変換辞書を使って、文字列に含まれる異体字をまとめて標準文字に置き換える関数です。
```python
def convert_text(text, conversion_dict):
	# 変換辞書を使ってテキストを変換
	for old, new in conversion_dict.items():
		text = text.replace(old, new)
	return text

# 使用例
converted_text = convert_text("鐡太郎 齋藤 髙橋 濵田", conversion_dict)
print(converted_text)  # 出力例： 鉄太郎 斎藤 高橋 浜田
```

### 変換辞書の保存
最後に、毎回HTMLをダウンロードして変換する必要のないように変換辞書を保存しておきましょう。
```python
# 変換辞書を保存
import json
with open('conversion_dict.json', 'w', encoding='utf-8') as f:
	json.dump(conversion_dict, f, ensure_ascii=False, indent=4)
```

## おわりに
異体字を標準的な文字に変換するプログラムを作成しました。これによって、歴史的な人名や地名を扱う作業がグッと楽になります。

ちなみに、旧字体の変換も同様の手法で可能です。上記の対応表でも旧字体はある程度変換できますが、変換できない旧字体もあります。そういうときは、旧字体に特化した変換表を見つけて来て、変換辞書を新たに作るだけでOKです。
WPFのここがすごい！


今回は私が普段業務で使っているWPFを紹介します🤗

# WPFとは？
Windows Presentation Foudationの略
Microsoftが提供するWindowsアプリケーション開発用のフレームワークです。

Windows Formsの後継といったところでしょうか。

XAML（ザムル）というXMLベースの言語でレイアウトを構築して、
中身の処理はXAMLとセットで作成されるxaml.csファイルで実装します。
（厳密にMVVMパターンを遵守する場合はxaml.csでないファイルに書くこともある）

例えば、アプリケーションを新規で作成するとMainWindow.xamlが作成されますが、
同時にC#を実装するMainWindow.xaml.csファイルも作成されます。

デフォルトのMainWindowにボタンを表示するとなると以下のような実装になります。

```MainWindow.xaml
<Window x:Class="WpfApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="簡易ボタン" Height="200" Width="300">
    <StackPanel>
        <Button Content="クリックしてください" 
                Click="Button_Click"
                Margin="10"/>
    </StackPanel>
</Window>
```

```MainWindow.xaml.cs
private void Button_Click(object sender, RoutedEventArgs e)
{
    MessageBox.Show("ボタンがクリックされました！");
}
```

# ここは任せて！
Windowsアプリケーションを作るためのフレームワークであることは理解いただけたと思いますが、「別にWindows Formsでよくない？」という方もきっといるでしょう…

なぜWPFを採用すべきなのか、まずはWPFの強みを紹介しましょう。

### グラフィック性能と表現力
- **ベクターベースの描画**
描画にはピクセルの集合体であるラスター形式ではなく、ベクター形式を採用しています。
点や線でグラフィックが構成されるため、拡大や縮小、回転も滑らかに実行できます。

https://321web.link/vector/

- **Direct3Dによるハードウェアアクセラレーション**
描画処理をGPUで行うため、CPU負荷が軽減され、高度な2D・3Dグラフィックスやアニメーションもスムーズに動作します。

https://learn.microsoft.com/ja-jp/windows/win32/getting-started-with-direct3d

ちなみに、ハードウェアアクセラレーションというカッコいい単語の意味は"コンピューターの処理を高速化するために、特定の処理をGPUや専用のハードウェアに任せる機能"のことです。

### 柔軟なUI設計とカスタマイズ性
- **XAMLによる宣言的なUI設計**
先ほど触れましたが、デザインはXAML、ロジックはC#と完全に分離しています。デザイナーと開発者の分業も容易ですね。

- **柔軟なレイアウトシステム**
GridやStackPanelを使って、複雑な画面構成も容易に実現できます。
ちなみに、Gridは行と列を宣言して任意の場所に配置できるやつで、StackPanelは複数のコントロールを多様な設定で並べることのできるやつです。

### 開発効率と保守性
- **データバインディング**
UIとデータを自動で同期させてくれます。C#コードで管理しているデータの複雑な状態管理などが必要なく、画面への描画が可能です。

- **MVVMパターンのサポート**
MVVMパターンで実装することが推奨されており、UIとロジックの分離が容易なため、保守性やテスト性の高いアプリケーションを構築できます。Prismなどのフレームワークと併用することでさらに強化されます。

# ここはちょっと苦手…
WPFの得意なことをつらつらと書き殴ってきましたが、もちろん苦手なこと（デメリット）もあります。

### 学習コストが高い
XAMLやMVVMパターン、データバインディング、独自の概念等もあって学習コストが高めです。（私もよく業務中に頭も抱えております）

### リソース集約型である
ハードウェアアクセラレーションを活用している一方で、メモリやCPU、GPUの消費が大きくなりがちです。古いPCやロースペックの端末においては真価を発揮できないこともあります。

### アプリサイズが大きい
WPFアプリケーションはファイルサイズが大きくなりやすく、ダウンロードやインストール時に帯域やストレージの負担が増えるという懸念点があります。

### クロスプラットフォーム非対応
Windowsアプリケーション専用のフレームワークなので当たり前っちゃ当たり前ですが、macOSやLinuxでは動作しません。普段私生活ではMacを愛用していますが、WPFを勉強しようと思ってもできません。（仕事で失敗したときの言い訳にはなりますね）

# まとめ
ざっくりとWPFの選定ポイントをまとめました。
| 要件                | WPFの適性 | 代替技術例          |
|---------------------|-----------|---------------------|
| 高品質UI            | ◎         | Avalonia UI         |
| Windows専用         | ◎         | Windows Forms       |
| クロスプラットフォーム| ×         | MAUI/Electron       |
| 低リソース環境       | △         | WinUI 3/UWP         |
| Web連携             | △         | Blazor/ASP.NET Core |

高品質のUIが求められるかつWindowsのみでの使用が確定しているアプリケーションには向いていると言えるでしょう。

ぜひ良いWPFライフを👏

# 参考
https://learn.microsoft.com/ja-jp/dotnet/desktop/wpf/overview/?view=netdesktop-9.0

https://www.software-developer-india.com/ja/wpf%E3%81%AE%E5%88%A9%E7%82%B9%E3%81%A8%E6%AC%A0%E7%82%B9%EF%BC%9F/
CloudWatch Logsと連携するMCPが出てた！

見つけました。

Log Analyzer with MCP

https://github.com/awslabs/Log-Analyzer-with-MCP

構成図がありました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/b61df1c3-3fca-430b-bf52-8bd3d103f732.png)

シンプル！

どんな機能があるかというと、

- CloudWatch ロググループを参照および検索する
- CloudWatch Logs Insights クエリ構文を使用してログを検索する
- ログの要約を生成し、エラーパターンを特定する
- 複数の AWS サービス間でログを関連付ける
- Claude のようなアシスタント向けに AI 最適化されたツール

やってみましょう。

## インストール

GitHubからCloneしてライブラリーを取得します。

```bash
git clone https://github.com/awslabs/Log-Analyzer-with-MCP.git
cd Log-Analyzer-with-MCP

uv sync
source .venv/bin/activate
```

Claude Desktopなどの設定は、このように行います。

```json
{
    "mcpServers": {
        "Log-Analyzer-with-MCP": {
            "command": "{絶対パス}/.venv/bin/python",
            "args": [
                "{絶対パス}/src/cw-mcp-server/server.py"
            ]
        }
    }
}
```

## やってみた

### ツール

ツールは全部で6個あります。

- correlate_logs
    共通の検索語を使用して、複数のAWSサービス間でログを相関させます。
- filter_log_events
    ロググループ内のすべてのストリームにわたって、パターンでログイベントをフィルタリングします。
- find_error_patterns
    ログ内の一般的なエラーパターンを見つけます。
- list_log_groups
    利用可能なCloudWatchロググループを一覧表示します。プレフィックスによるフィルタリングも可能です。
- search_logs
    CloudWatch Logs Insightsクエリを使用してログを検索します。
- summarize_log_activity
    指定された期間のログアクティビティの概要を生成します。

こんなことができます。

> Lambdaに関するロググループを取得して

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/476ce91b-4c5d-4f75-9b13-bba8fafa6dd8.png)


### リソース

あまりMCPで取り上げられませんが、リソースにも対応しています。
このボタンをクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/6a0b27cf-48c2-41a6-9077-0e9c8e5a679d.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/7ed58eba-bf3a-4ff3-a09b-b3278f0d8178.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/b5a8add2-f64c-4d79-9a63-051ca88bc02b.png)

すると、添付ファイルがセットされます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/51f2002a-89b0-4131-9c34-8265d267a38b.png)

内容はこんな感じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/366f6f2f-4e2a-4fc0-b61e-b47903772bee.png)

すごく凝っているわけではないですが、どのように分析するかの内容が記載されています。

```text
bedrock-invoke-logging-us-east-1 ロググループから、以下の CloudWatch ログを分析してください。

まず、ロググループに関する情報をいくつか取得します。
1. ロググループの基本的な構造を把握し、ログの形式を理解してください。
2. 最近のエラーがないか確認してください。
3. ログボリュームのメトリクスを調べてください。
4. 最近のログのサンプルを分析してください。

この情報に基づいて、以下の作業を行ってください。
- 繰り返し発生するエラーや例外を特定してください。
- 異常なパターンや異常を探してください。
- 見つかった問題の根本原因を提案してください。
- 問題を解決または軽減するためのアクションを提案してください。
- パフォーマンスやリソース使用率に関する分析情報を提供してください。

必要に応じて、以下の追加情報をお知らせください。
- 他のサービスのログとの相関関係
- 分析対象期間のより具体的な指定
- 特定のエラーメッセージやイベントのクエリ
```

チャット欄には特に何も入力せず、処理を開始させます。
ただ、トークンが超過しているのか、無料プランではエラーになりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/6c1e5662-8fc3-4145-a0c7-a8b02b099d8d.png)

そのため、Streamliで画面を作成して動作させてみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/5a56db9c-3e29-4eb4-bffe-d2a2a05c0f16.png)

わかりやすく分析してくれます！


ログを扱う性質上、かなり大量のデータを扱ってる雰囲気です。トークン消費量がちょっと気になりますね。
モジュールの独立性が高い順番について

## モジュールの独立性が高い順番について
モジュール結合度は他のモジュールとのデータの受け渡しに関して、渡すものや受け渡し方法について分類されている。
以下、上からモジュールの独立性が高い順に並べていく。
**データ結合**：単一のデータを引数として受け渡す
**スタンプ結合**：データ構造を引数として受け渡す
**制御結合**：制御パラメータを引数として受け渡す
**外部結合**：外部のモジュールで定義されたデータを参照する
**共通結合**：グローバル領域に定義されたデータを参照する
**内容結合**：ほかのモジュール内のデータを直接参照する
EntraIDで特定のグループに参加するユーザー情報を抽出してみた

IT企業で働いている人は謎の棚卸や情報適用を求められることがあると思います。
(監査対応のためやら脆弱性の対応のためやら。。。
多分システム提供する上でそういう棚卸とか情報適用してないとダメなんでしょうね。。
その辺も上位層の対応も追々勉強したいところです)

今回はアカウントの情報を求められたときに使えそうなスクリプトを
Copilotに全力で頼んで作ってもらいました。


```powershell:test.ps1
# Microsoft Graph PowerShellモジュールをインストール（初回のみ）
# 初回実行時のみ必要。Microsoft Graph APIと連携するためのモジュールを追加。
Install-Module Microsoft.Graph -Scope CurrentUser

# Microsoft Graph APIに接続
# 認証を行い、ユーザー情報とグループ情報の取得を可能にする。
Connect-MgGraph -Scopes "User.Read.All", "Group.Read.All"

# 出力するCSVファイルのパス(自由に変えてください)
$outputFile = "C:\Users\Public\FilteredAzureAD_UserGroups.csv"

# "test01" または "test02" を含むグループのみを取得（取得時点でフィルタリング）
# ここでフィルタリングすることで、大量のデータを取得しないように最適化。
$filteredGroups = Get-MgGroup -Filter "startswith(DisplayName, 'test01') or startswith(DisplayName, 'test02')"

# ユーザー情報を格納する配列を準備
$results = @()

# フィルタリングされたグループごとにユーザー情報を取得
foreach ($group in $filteredGroups) {
    # グループに所属するメンバーの情報（ObjectIdのみ取得）
    # `Get-MgGroupMember` はメンバーのObjectIdを返すため、後でUPNと表示名を取得する必要がある。
    $members = Get-MgGroupMember -GroupId $group.Id

    # 各メンバーのObjectIdを使ってユーザー情報を取得
    foreach ($member in $members) {
        # `Get-MgUser -UserId` を使って、各ユーザーのUPNと表示名を取得
        $user = Get-MgUser -UserId $member.Id 
        
        # ユーザー情報をオブジェクトとして配列に追加
        $results += [PSCustomObject]@{
            GroupName = $group.DisplayName  # 所属グループ名
            DisplayName = $user.DisplayName # ユーザーの表示名
            UPN = $user.UserPrincipalName  # ユーザーのUPN（ログインID）
        }
    }
}

# CSVの内容をUTF-8（BOM付き）で保存する処理

# ① `ConvertTo-Csv` でデータをCSV形式に変換
#    - PowerShell標準の `Export-Csv` はデフォルトでUTF-16を使用するため、Excelで文字化けすることがある。
#    - `ConvertTo-Csv` は、データを「文字列」として扱うので、自由にエンコーディングを設定できる。
#    - `NoTypeInformation` を指定することで、余計な型情報（`#TYPE System.Object` など）を含めずに出力する。
$csvContent = $results | ConvertTo-Csv -NoTypeInformation

# ② Excelが正しく開けるように UTF-8 (BOM付き) のエンコーディングを設定
#    - BOM（Byte Order Mark）は、ファイルの先頭に付加される特別なマークで、エンコーディングの種類を示す。
#    - UTF-8にはBOM付きとBOMなしがあり、Excelは「BOMなしのUTF-8」をうまく認識できないことがある。
#    - `New-Object System.Text.UTF8Encoding $true` を使うことで、UTF-8 (BOM付き) を作成。
#    - こうすることで、Excelで開いたときに日本語の文字化けを防ぐことができる！
$utf8BOM = New-Object System.Text.UTF8Encoding $true

# ③ `WriteAllLines` を使用して、UTF-8 (BOM付き) でファイルを保存
#    - `.NET の System.IO.File.WriteAllLines()` を使うことで、文字列を指定したエンコーディングでファイルに保存できる。
#    - PowerShell標準の `Export-Csv` ではUTF-16が使われるため、Excelでの互換性が悪い。
#    - `WriteAllLines` を使い、UTF-8 (BOM付き) で保存することで、Excelで正しく開けるようにする。

# `.NET の System.IO.File.WriteAllLines()` の構文:
# [System.IO.File]::WriteAllLines(ファイルパス, CSVデータ, 文字コード)
# - 第1引数: 保存先のファイルパス (`$outputFile`)
# - 第2引数: CSVデータ (`$csvContent`)
# - 第3引数: エンコーディング (`$utf8BOM`)
[System.IO.File]::WriteAllLines($outputFile, $csvContent, $utf8BOM)

# 処理完了メッセージを表示
Write-Output "UTF-8 (BOM付き) のCSVファイルが作成されました: $outputFile"
```

GUIの操作だとグループ名で絞ってUPN含むユーザー情報抽出して・・・
っていうかゆい所に手が届かず必要な情報をいい感じに抽出できませんでしたが
これでできるようになりました。やったね。

###### 余談-Copilot(コピくん)とのやりとり
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1885188/e11c19d1-4164-47e1-871e-7759d6d35daf.png)

できないことを自信満々にできると言い続けるのかわいい
✅ export default vs export constの違いまとめ


# :point_up:Back to Basic 
:thinking:開発時に、意外と頭の中がこんがらがったりするので、備忘録として記載します。（自分のため）

| 特徴| ```export default``` | ```export const```（名前付きエクスポート） |
|:-:|:-:|:-:|
|  エクスポートの仕方 | 1ファイルにつき1つだけ「デフォルト」で出せる | 複数個の関数や変数などを「名前付き」で出せる
| インポートの書き方 | ```import Something from './xxx'``` | ```import { Something } from './xxx'```|
| リネーム | インポート時に好きな名前で呼べる → ```import AnyName from './xxx'``` | ```{ Something as AnyName }```などと書く必要がある|
| 主な使いどころ | そのファイルの「メインの中身」を渡すとき | ユーティリティ関数や複数の定数など|




## 🧠 わかりやすい例で📝
### 1. export default
```tsx

// components/Button.tsx
const Button = () => <button>Click</button>;
export default Button;
```
```tsx

// 他のファイルで
import Button from '@/components/Button';
```
✅ ファイルの「主役」を export したいときに使うイメージ

### 2. export const（名前付きエクスポート）
```tsx
// utils/math.ts
export const add = (a: number, b: number) => a + b;
export const multiply = (a: number, b: number) => a * b;
```
```tsx
// 他のファイルで
import { add, multiply } from '@/utils/math';
```
✅ 複数のものをまとめて出したいときに便利



## 🧭 いつ使い分ければいいの？
|目的|推奨されるスタイル|
|:-:|:-:|
コンポーネント（1つだけを渡す） | ✅ export default
複数の関数や定数を渡す | ✅ export const（名前付き）
ライブラリ的に使いたい | ✅ export const（メンテ性◎）

## 💡補足：チームやプロジェクトのポリシーにもよるので注意が必要
大規模チームでは 名前付きエクスポート統一 というルールにしてることも多い気がする。
なぜなら、「名前付きだと自動補完が効いてわかりやすい」からかという認識。

### 🎯 結論（どっちが正しい？）
👉 どっちも正しい。目的に応じて使い分けるのが◎！
Fabric SQL分析エンドポイントでのユニークな挙動

## ユニークな挙動
Microsoft FabricのSQL分析エンドポイントでSQLクエリを書いている際に、
以下のようなユニークな挙動に遭遇されたことはありますでしょうか？

右からバーが迫ってきて、書いたクエリが見えなくなってしまいます。

![ビデオ プロジェクト 1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3850932/8d2e9554-8f49-4717-a717-edb728a74c4f.gif)


画面の倍率を変更することで、発生、解決することを確認したので、
困っている、見てみたい方はぜひ試してみてください！
モジュール設計について

## モジュール
モジュールとは、プログラム中の特定機能を持ったひとまとまりの構成部分である。モジュール内部の関連性が高く、モジュールの独立性が高い状態をモジュール強度が強いという。
モジュール強度が強いと、他のモジュールとの関連性を考慮する必要が少なくなり、メンテナンスなどの保守が効率的になる。
Controller:Service:DB参照のリファクタリングについて　勉強記録

# 今回学んだこと
・orElseThrowによるエラーページのリファクタリング
・Contorollerクラスからのデータの所得
・その他のリファクタリング

## リファクタリング前後のコードの変化
<dl>
    <dt>リファクタリング前<dt>
<dl>

``` TaskContoroller.java
    @GetMapping("/{id}/editForm")
    public String showEditForm(@PathVariable("id") long id, Model model) {
        var taskEntity = taskService.findById(id)
                        .orElseThrow(() -> new IllegalArgumentException("Task not found"));
        var form = new TaskForm(taskEntity.summary(), taskEntity.description(), taskEntity.status().name());
        model.addAttribute("taskForm", form);
        return "tasks/form";
    }
```

<dl>
    <dt>リファクタリング後<dt>
<dl>

```TaskContoroller.java
@GetMapping("/{id}/editForm")
    public String showEditForm(@PathVariable("id") long id, Model model) {
        var form = taskService.findById(id)
                .map(TaskForm::fromEntity)
                .orElseThrow(TaskNotFoundException::new);
        model.addAttribute("taskForm", form);
        return "tasks/form";
    }
```

## 解説
前提としてContorolerクラスは見やすくわかりやすく書く,意識として↓
| 理由 | 内容 |
|:-:|:-:|
| 💡 役割が限られているから  |  接続役としてだけに専念するべき |
|  🧹 責任を分けたいから | サービスやリポジトリと分業  |
|  🔧 メンテしやすいから | 見通しが良くなり、バグも見つけやすい  |
|  🔁 変更に強いから | 他の層に影響を与えずに変更できる  |

<dl>
    <dt>リファクタリング前(主な動作）</dt>
    <p>まず@GetMapping("/{id}/editForm")でurlが指定された時にGetするメソッドとして定義する。
    
まず@GetMapping("/{id}/editForm")でurlが指定された時にGetするメソッドとして定義する。

editFormを作るためのメソッドなのでString型のshowEditFormとして@PathVariableを使ってurlのidを変数として受け取り、さらにmodelでビューに返す（Tymeleafを使用しているのでJsonで返すときは別）

リファクタリング前でtaskEntityを定義してサービスクラスのfindByIdを呼び出しDBからidを所得している

.orElseThrow(() -> new IllegalArgumentException("Task not found")でOptional型が返された時にidが違った場合、Task not foundを返す文である。

model.addAtributeで"taskForm"がビュー側で呼び出された場合formというDBにアクセスしたいのでtaskEntityからデータを取り出し画面表示用のTaskFormをnewしている
</p>

<dt>リファクタリング後</dt>
<p>主な変化として定義する変数をformひとつにし、.mapを使うことで可読性が高い文章になっている

.map(TaskForm::fromEntity)の役割としてTaskEntity → TaskForm に変換する 静的メソッド（static method） である。リファクタリング前のTaskFormに書いてあった引数をTaskFormの性的メソッドの中にTaskForm fromEntityと定義することで簡潔に書いている。

.orElseThrowの中はTaskNotFoundExseptionという例外クラスを作ることで簡潔に書いている
</p>
</dl>

## 外伝：例外クラス

```TaskNOtFoundException.java
@ResponseStatus(HttpStatus.NOT_FOUND)
public class TaskNotFoundException extends RuntimeException{
}
```

<dl>
    <dt>重要なパターン</dt>
    <p>
・@ResponseStatus(HttpStatus.NOT_FOUND)
　→ この例外が発生したときに HTTPステータスコード「404」 を返すように指示してる
 
・extends RuntimeException
　→ チェックされない例外（Unchecked Exception） として扱うことで、throws 書かなくてOK
    </p>
</dl>

# まとめ
それぞれの役割ごとにクラスを分けて書くことでエラーに対処しやすくなり可読性が高いプログラムになることが理解できた。tymeleafを使うか使わないかで大きな差が出るが３層アーキテクチャの考え方は重要であることがわかった。なるべく変数は少なくコードは短く！！
（文字多くてごめんね）
何が悪いんだろうか？


Superbadgeもうまくいかんし、Apexも何が悪いんだか...

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/268e2f37-76d8-4308-a1aa-05e3499b0285.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/98c3b4e7-fae8-498e-a5e5-bc64891bae15.png)


分からん

もう今日は止めよう。8時間かかっても、３しかクリアーできなかった


```
List<Contact> updateContactList = new List<Contact>();
Set<String> ContactSet = new Set<String>();

ContactSet.add('Abigail Mason;abbiemason@example.com');

Set<String> xxxSet = new Set<String>():
Map<String,String> xxxMap = new Map<String,String>();
for (String con : ContactSet){
    List<String> xxx = con.Split(';');
    xxxSet.add(xxx[0]);
    xxxMap.put(xxx[0],xxx[1]);    
}

List<Contact> ContactList = [select Id,Name from contact where Name =: xxxSet];
for (Contact con : ContactList){
    Contact c = new Contact();
    c.Id = con.Id ;
	String e = (String)xxxMap.get(c.Name);
    if (e != null) {
        c.email = e;
    	updateContactList.add(c);    
    }   
    
}
```

:になっていた!!!!


```
List<Contact> updateContactList = new List<Contact>();
Set<String> ContactSet = new Set<String>();

ContactSet.add('Abigail Mason;abbiemason@example.com');

Set<String> xxxSet = new Set<String>();
Map<String,String> xxxMap = new Map<String,String>();
for (String con : ContactSet){
    List<String> xxx = con.Split(';');
    xxxSet.add(xxx[0]);
    xxxMap.put(xxx[0],xxx[1]);    
    system.debug('*******xxx***' + xxxMap);
}

List<Contact> ContactList = [select Id,Name from contact where Name =: xxxSet];
system.debug('***********' + ContactList.size());
for (Contact con : ContactList){
    Contact c = new Contact();
    c.Id = con.Id ;
	String e = (String)xxxMap.get(con.Name);
    system.debug('********e***' + e);
    if (e != null) {
        c.email = e;
    	updateContactList.add(c);    
    }   
    
}
system.debug(updateContactList.size());
if (updateContactList.size() > 0) update updateContactList;
```
ゲストアカウント（B2B）でMicrosoft Fabricを開発する際の注意点

## はじめに
外部テナントに招待され、ゲストアカウントでFabricを開発する際、
いくつかの制限があり、困ったので共有しておきます。　(※2025年4月時点の制限です)

その他の制限についてご存じでしたら、コメントなどでご教示いただけると幸いです。

## ゲストアカウントの制限
### ① データフローGen2でゲストテナント内のソースに接続できない

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3850932/452ec95d-4386-4627-b4bf-6b6b317b214a.png)

https://learn.microsoft.com/ja-jp/fabric/data-factory/data-factory-limitations#data-factory-dataflow-gen2-limitations


### ② Git統合で同期とコミットができない

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3850932/27fa5abf-5c07-45d5-aab1-863ff390ce47.png)

https://learn.microsoft.com/ja-jp/fabric/cicd/git-integration/intro-to-git-integration?tabs=azure-devops#considerations-and-limitations
動画をダウンロードする最も簡単な方法：SSYouTube.online のご紹介 – 頼れるYouTubeダウンローダー

オンラインコンテンツが主流の現代では、信頼性の高い [YouTube downloader](https://ssyoutube.online) をいつでも使えるようにしておくことが不可欠です。動画をオフラインで視聴するために保存したり、ポッドキャスト用の音声を抽出したり、役立つチュートリアルをアーカイブしたりする場合でも、強力で使いやすいツールがあれば状況は大きく変わります。SSYouTube.onlineは、お気に入りのYouTube動画をわずか数クリックでダウンロードできる、高速、安全、そしてシンプルなソリューションです。

**SSYouTube.onlineとは？**

SSYouTube.onlineは、YouTube動画をデバイスに直接保存できる無料のWebベースのYouTubeダウンローダーです。複雑なソフトウェアやアプリは必要ありません。動画リンクをコピーしてWebサイトに貼り付けるだけで、お好みの形式でダウンロードできます。とても簡単です。

**SSYouTube.onlineを選ぶ理由**

SSYouTube.onlineが、数ある動画ダウンローダーの中でも際立っている理由をいくつかご紹介します。

**1. インストール不要**
アプリやソフトウェアのダウンロードは不要です。このウェブベースのYouTubeダウンローダーはブラウザ上で完全に動作するため、高速、安全、そして便利です。

**2. 複数のフォーマットオプション**
動画をMP4でダウンロードしたいですか？音声だけをMP3でダウンロードしたいですか？SSYouTube.onlineは複数のダウンロードフォーマットをサポートしており、ニーズに合わせて柔軟に選択できます。

**3. 高速で信頼性の高いダウンロード**
このツールの最大の特徴の一つは、そのスピードです。SSYouTube.onlineなら、長い動画でもダウンロードが高速です。

**4. モバイルとデスクトップに対応**
スマートフォン、タブレット、デスクトップなど、あらゆるデバイスに最適化されています。主要なブラウザとオペレーティングシステムでスムーズに動作します。

**5. 登録不要**
アカウントの作成やサインアップは不要です。サイトにアクセスし、YouTubeのURLを貼り付けるだけでダウンロードできます。

**SSYouTube.online の使い方**

SSYouTube.online の使い方は至って簡単です。

**1.** YouTube にアクセスし、ダウンロードしたい動画を探します。

**2.** 動画の URL をコピーします。

**3.** ssyoutube.online にアクセスします。

**4.** 入力ボックスに URL を貼り付けます。

**5.** ご希望の形式と画質を選択します。

**6.** ダウンロードをクリックして、お楽しみください！

**まとめ**

高速で安全、そして手間のかからない YouTube ダウンローダーをお探しなら、SSYouTube.online は間違いなくブックマークしておく価値があります。様々な形式で YouTube 動画をダウンロードできる、最もシンプルで効果的なツールの一つであり、ほぼすべてのデバイスでスムーズに動作します。

長時間のフライトに備えて動画を保存したい場合、独自のメディアライブラリを作成したい場合、あるいは単にオフラインでコンテンツを楽しみたい場合など、SSYouTube.online があらゆるニーズに対応します。
MCPサーバーをWeb APIと比較してみる

MCPサーバーとWebAPI（以下API）は異なる目的を持つ技術ですが、両方とも外部サービスとの連携を実現するコンポーネントです。以下で比較していきます。

| 特性 | API | MCPサーバー |
| --- | --- | --- |
| 基本的な目的 | 特定の機能やデータへのアクセスを提供する | AIモデルと外部サービスを統合するためのプロトコル |
| 設計思想 | クライアント-サーバー型の直接的な通信 | AIエージェントのためのツール統合プラットフォーム |
| 主要な機能 | データの送受信、計算処理 | ツール管理、ワークフロー制御、リソース統合  |
| 柔軟性 | 固定されたエンドポイントと機能 | 動的ツール追加とカスタマイズが可能 |
| 通知機能 | 通常はなし | リソース変更のリアルタイム通知が可能 |
| セキュリティ | 基本的な認証機能 | ツールレベルでのアクセス制御が可能 |

```mermaid
flowchart LR
    classDef api fill:#FFE6CC,stroke:#D79B00,color:#000
    classDef mcp fill:#DAE8FC,stroke:#6C8EBF,color:#000

    subgraph API["API"]
        direction TB
        A1[クライアント]:::api -->|"リクエスト"| B1[APIサーバー]:::api
        B1 -->|"レスポンス"| A1
        C1[データベース]:::api -.->|データ保存| B1
    end

    subgraph MCP["MCPサーバー"]
        direction TB
        M1[MCPホスト]:::mcp -->|"ツール呼び出し"| S1[MCPサーバー]:::mcp
        S1 -->|"ツールリスト"| M1
        S1 -->|"リソース通知"| M1
        T1[ツール]:::mcp -->|"実行"| S1
        R1[リソース]:::mcp -->|"管理"| S1
    end

```

上記の図について補足説明します：

- 色分け：
    - オレンジ系：従来のAPI方式のコンポーネント
    - 青系：MCPサーバーのコンポーネント
- 矢印：
    - 実線（→）：直接的なリクエスト/レスポンスの流れ
    - 点線（-.>）：データの依存関係や管理関係
- 主要な違い：
    - API方式は単純なクライアント-サーバー構造
    - MCP方式はツールとリソースを通じた多層的な統合を実現

### 具体的な使用のコード例

APIの典型的な使用のコード例：

```python
# シンプルなAPI呼び出し
response = requests.get('<https://api.example.com/users>')
data = response.json()

```

MCPサーバーの使用のコード例：

```python
# SQLiteデータベースを操作するMCPサーバー
@app.call_tool()
async def call_tool(name: str, arguments: dict):
    if name == "get-top-products":
        date = arguments.get("date")
        limit = arguments.get("limit", 5)
        # データベースクエリ実行
        products = db.query("SELECT * FROM products ORDER BY sales DESC LIMIT ?", limit)
        return [types.TextContent(type="text", text=str(products))]

```

### 実践的な活用例

APIの活用例：

- Webサービスとの連携
- データ取得・更新
- 認証・認可処理

MCPサーバーの活用例：

- GitHubリポジトリの分析と自動化
- データベース操作の統合
- ファイルシステムとの連携
- AIエージェントによるワークフロー自動化
studyMemo_コンスタントプールについて

# 初めに
すずきです。
Javaのコンスタントプールについて学習したので備忘として残しておきます。
おかしな部分がありましたらご指摘いただけますと幸いです。

# コンスタントプールとは
コンスタントプールとは**文字列リテラル**を使ってインスタンスを作成した際に文字列をメモリ上に定数として登録しておき、同じ文字列がインスタンス化された際にそのメモリを再利用しするという仕組みです。

# 例
本来Javaでは複数のインスタンスを作成した場合、複数のメモリ上にインスタンスを生成しそれぞれの参照値が変数に代入されるが、Stringクラスではコンスタントプールの仕組みを使うことで同じ文字列を複数作成しても新しい変数に対して同一の参照値を返すことになり「==」による同一性(参照値)の比較を行ってもtrueを返すこととなる。

```java:Sample.java
public class Sample {
    public static void main(String[] args) {
        String str1 = "Sample";
        String str2 = "Sample";
        System.out.println(str1.equals(str2)); //同値性("Sample"という値)の比較->true
        System.out.println(str1 == str2); //同一性(保存されているメモリの位置)の比較->true
    }
}
```

# まとめ
繰り返しになるがコンスタントプールとは文字列リテラルを使ってインスタンスを生成した際のメモリを節約するための仕組みであり、これにより同一性の比較をした際の挙動がほかのクラスと異なったものになる。
ただしnew演算子を使ったインスタンス生成(new String())では明示的に新しいインスタンスを生成しているので注意が必要である。
[備忘録]React/Typescript+Vite+Tailwind CSSの開発init[2025年4月]

Gafuと申します！エンジニアではないです。
本業は製薬企業で医薬品研究職をしてます。
React/Python/Rとかとか勉強して、業務に役立てていきたいと考えてるので、ここを備忘録まとめ場所とします。【初学者】

今回はReact/Typescript+Vite+Tailwind CSSのinitで謎に躓いたのでまとめてます。


✅ Vite プロジェクト作成(Typescript)
```bash
npm create vite@latest projectName -- --template react-ts
```

🚶 ディレクトリ移動
```bash
cd projectName
```

🌪️ Tailwind CSSのinstall
```bash
npm install tailwindcss @tailwindcss/vite 
```

🖥️ 開発プレビュー立ち上げ
```bash
npm run dev
```

⚙️configの編集
```vite.config.ts
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import tailwindcss from '@tailwindcss/vite'

// https://vite.dev/config/
export default defineConfig({
  plugins: [react(), tailwindcss()],
})
```

📖Tailwind CSSをindex.cssに読み込む
```index.css
@import "tailwindcss";

これ以外は全部消す
```

これだけでした。。。
なんでできひんかったんでしょうか。
普通に前の環境が残ってただけかも、もしアドバイス等あれば気軽に連絡いただけると嬉しいです！

おわり
ネットワークスペシャリストに頻出するOSPFのLSA

OSPF(Open Shortest Path First)のLSA(Link State Advertisement)5種類を一覧化

|LSA Type|詳細|
|:---:|---|
|Type1|ルータLSA。全てのOSPFルータによって作成される。**超頻出**|
|Type2|ネットワークLSA。代表ルータによって作成される。**超頻出**|
|Type3|ネットワークに到達する経路のサマリLSA。ABR(Area Border Router)によって作成される。|
|Type4|AS boundary router に到達する経路のサマリLSA。ABRによって作成される。|
|Type5|外部LSA。ASBR(Autonomous System Boundary Router)によって作成される。R6のPM1-2でTypeを解答する問題として出題された。:scream: :scream_cat: |
ORMとDAOの役割と違い：なぜ分けるのか？どう便利なのか？

## はじめに

Webアプリケーションを作っていると、

「モデル」「DAO」「ORM」など、似たような言葉がよく出てくる。

この記事では、それぞれの役割・違い・使い分け方を整理する。

---

## モデルとは？

モデルは「**1つのレコード（データの1行）を表現するオブジェクト**」。

名前・説明・種類などの属性（データ）を持ち、必要に応じて振る舞い（メソッド）も含まれる。

---

## DAOとは？

DAO（Data Access Object）は「**データベースとやり取りする専用のオブジェクト**」。

モデルとは別に、SQLを使ってデータを保存・取得・更新・削除する責任を持つ。

DAOを使うことで、MySQL版のDAO、Memcached版のDAOなど、**データベースの種類ごとに使い分けが可能**になる。

---

## ORMとは？

DAOの定型処理（CRUD）は、どのテーブルでも毎回必要。

それを**毎回手で書くのは面倒**なので、共通の抽象クラス（ベースクラス）にまとめる。

それが ORM（Object-Relational Mapping）。

ORMを使えば、モデルクラスがこの抽象クラスを継承するだけで、自動的にテーブルと紐づき、**create / find / update / delete** のような操作が使えるようになる。

---

## まとめ

- **モデル**：データ1件をオブジェクトで表現（＋振る舞いもOK）
- **DAO**：データベースとのやりとりを担当（MySQL / Redisなど切替可能）
- **ORM**：DAOのCRUD操作を抽象化し、モデルから簡単に操作できるようにする仕組み

ORMを使えば基本操作を一気に共通化でき、DAOやモデルに集中しやすくなる。

複雑な処理だけを個別に実装すればよくなるので、**効率的で保守性も高い構成**になる。
Gitの基本

# Gitの初期設定
**名前とメールアドレスを設定する**
```
$ git config --global user.name '名前'
$ git config --global user.email 'メールアドレス'
```
**Gitの設定確認**
```
$ cat ~/. gitconfig
```
**Gitのマニュアルを表示する**
```
$ man git
```
# コミットができる
### 1\.ローカルリポジトリ作成→GitHubへ追加・管理する方法

<img width = "700" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4052007/693f4d88-f904-44f5-b390-05515f2e3d97.png">


**ローカルリポジトリの新規作成**
```
$ git init
```
<img width = "70"src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4052007/d5b2f4c5-f656-4d98-b9c7-b3e23ed9e03d.png">　　　←`.git`ディレクトリが作成された


**変更をステージする**
```
$ git add -A(ファイル名)
```
　`-A`または`.`：すべてのファイルをインデックスに登録する

**リモートリポジトリ先URLを確認する**
```
$ git remote -v
```


**リモートリポジトリ先URLを指定する**
```
$ git remote add origin リモートリポジトリURL
```

**リポジトリに変更履歴を記録する(コミットする)**
```
$ git commit -m '変更履歴や内容'
```
**リモートリポジトリへ変更を送る(プッシュする)**

```
$ git push -u origin main
```
- `-u`：次回から省略できる

### 2\.GitHubで編集した内容をローカルリポジトリへ反映させる


- 反映させたいフォルダへ移動する
- リモートとローカルリポジトリ　＊の位置を確認し、
**＊main**がリモート側になっていることを確認する
- pullでローカルリポジトリに変更が上書きされる
 ```
 $ cd
 $ git branch -a
   *main
   
 $ git pull (-u指定あるため省略)
 ```
 

### 3\.GitHub→ローカル上にダウンロードして編集する方法
- `cd`でダウンロードするローカルファイルまで移動する
- リモートリポジトリをダウンロードする　
```
$ cd
$ git clone リモートリポジトリURL(HTTP)
```

### その他コマンド


**変更状況を確認する**
```
$ git log
```

**ワークツリーの変更を元に戻す/取り消す**
```
$ git restore .(ファイル名)
```
- `-staged`：ステージ(インデックス)からワークツリーへ

**コミットを取り消す**
```
$ git revert 
```

**状態を確認する**
```
$ git status
```

**差分を表示する**
```
$ git diff
```

# GitHub を使って開発を進めることができる


**リモートのブランチをローカルのブランチに反映させる**

```
$ git pull origin main
```
※`-u`の設定がされていれば、`origin main`は不要。


## ブランチを利用して開発を進めることができる
**ブランチ一覧を表示する**
```
$ git branch
```

**新しいブランチを作成する**
```
$ git branch ブランチ名
```

**ブランチを切り替える**
```
$ git switch 移動先ブランチ名
```

  ①ブランチの切り替えを確認すると......
```
$ git branch 
＊feature-name
  main
```
②feature-nameブランチをマージする
　別のブランチに変更を取り込むこと
```
$ git merge マージするブランチ名
```

③ブランチを削除する
　マージ後、分岐していたfeature-nameブランチが不要になるため削除する。
```
$ git branch -d feature-name
```

**GitHub フローに従って開発を進める**

https://docs.github.com/ja/get-started/using-github/github-flow

## プルリクエストとは　
自分の変更したコードをリポジトリに取り込んでもらえるよう依頼する機能のこと

<img width="700" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4052007/f7935ba1-96e6-40dd-bd1d-7e2453dfb991.png">





***************
**[参考動画]だれでもエンジニア / 山浦清透:Gitの基本コマンドまとめ【Git入門講座#3】**

https://www.youtube.com/watch?v=f4BRgGAXyek
個人開発　Habitica-外部連携　ログ設計


# ログ設計の目的
・障害発生時に発生原因や障害影響を対処しやすくするため
・障害発生時に発生原因や障害影響を調べるため（障害対応）
・監査対応時に業務状況を証明するため（監査対応）


# インプットとなる成果物


「個人開発　Habitica-外部連携　概念設計」
4.ユースケース記述/自前で実装する機能/バッチ処理側

参照

https://qiita.com/RYA234/items/675442e8a2acc17c0f3e#abitica%E3%81%AE%E3%82%BF%E3%82%B9%E3%82%AF%E3%82%92%E3%83%87%E3%83%BC%E3%82%BF%E3%83%99%E3%83%BC%E3%82%B9%E3%81%AB%E6%9B%B8%E3%81%8D%E8%BE%BC%E3%82%80
# 成果物
## API取得するまでの流れ
```plantuml
@startuml
title:API呼び出し時の動き \n 目的：例外処理の部分を洗い出すため
start
:URI パラメータ \nアクセストークン準備;

:APIを実行する;

if(ネットワークに繋がっている？) then (YES)
 else (no)
 end
endif
if(URIが違う) then (YES)
 else(no)
 end
endif

if(アクセストークンが違う) then (YES)
 else(no)
 end
endif

:レスポンス取得;

if(レスポンスが一件以上表示されるか) then (YES)
 else(no)
 end
endif

if(レスポンスの形式が合っているか) then (YES)
 else(no)
 end
endif
end

@enduml


```


## DBに書き込みの流れ
```plantuml
@startuml
title:データベースアクセス インサートする \n 目的：ログ設計で関わる例外処理の部分を洗い出すため
start
: DB接続文字列作成;


if(データアクセスできるか？) then (YES)
 else (NO)
 end
endif
if(テーブルが存在しない？) then (YES)
 else(NO)
 end
endif

if(カラムに入る値と型が異なる？) then (YES)
 else(NO)
 end
endif

if(クエリタイムアウトエラー？) then (YES)
 else(NO)
 end
endif

:レコード書き込み完了;

end

@enduml

```


## ログフォーマット
項目名|値|説明
------|--|-----
日時|YYYYMMDDhhmmss|メッセージの出力日時
レベル| INFO もしくは WARN もしくは ERROR|メッセージの分類
メッセージID|個別|
メッセージ|個別|


## ログ出力先
task_collect_tool/src/batch/Habitica/task/log.txt

## ログ出力タイミング
・処理が完了したとき
・処理の途中で例外処理が発生した時に発生する。

## メッセージ分類

分類|エラーコード|備考|
----|-----------|--------------|
エラー|Error|処理が中止される場合に出力される（例外）今回の場合はシステム上の例外のみ
警告|Warning|
通知|Info|正常処理のメッセージ



## ログメッセージ一覧

分類|エラーコード|エラーメッセージ|備考
---|----|---|---
Error|28P01|データベースアクセスです。| PostgreSQLの標準エラーを利用
Warning|23505|主キー重複エラーです。|PostgreSQLの標準エラーを利用
Error|42P01|対象のテーブルが存在しません。|PostgreSQLの標準エラーを利用
Error|22XXX|カラムに入る値と型が異なります。|PostgreSQLの標準エラーを利用
Error|08003|クエリタイムアウトエラーです。|PostgreSQLの標準エラーを利用
Error|001|ネットワークが繋がっていません。| HTTP403
Error|002|Habiticaのアクセスキーが違います。| HTTP401
Error|003|レスポンスの取得結果が１件もありません| HTTP200
Error|004|レスポンスの形式があっていません。|HTTP200
Info|005|処理が完了しました。|

## クラス図

```plantuml
@startuml
title:ログクラス関係のクラス図

class  "HaibiticaTaskRepository" as Repository
class "HabiticaTaskService" as Service
class "HabiticaTaskApi" as Api
class "CustomLog" as Log

Repository --> Log :use
Service --> Log: use 
Api --> Log: use

Log : info() :void
Log : error() :void
Log : warning() :void

@enduml

```


# 感想
例外設計とログ処理がごっちゃになってますね。
後日しっかりブラッシュアップします

各外部連携方法（ファイル、DB,API）の異常系処理を洗い出して、アクティビティ図にまとめておく良いと思いました。
（毎回明確な基準がないまま進めてるから、時間もかかるし漏れあるし）

# 参考書籍
## ログフォーマット　ログ出力先　 
書籍：システム設計の謎を解く　p253


## ログ管理　運用
書籍：運用設計の教科書　4.6ログ管理


## postgresqlのエラーについて
https://www.postgresql.jp/docs/9.4/errcodes-appendix.html
【一問一答】令和7年ネスぺ試験出題予想をDeepResearchに聞いてみた

# ネットワークスペシャリスト試験 2025：最新技術キーワード集（一問一答形式）

この記事では、2025年4月のネットワークスペシャリスト試験（午後II重視）で押さえておきたい最新技術・トレンドを、一問一答形式でコンパクトにまとめています。学習や振り返りにお役立てください。

---

## 1. Wi‑Fi 7（IEEE 802.11be）
- **問:** Wi‑Fi 7 の最大理論通信速度は？  
  **答:** 46 Gbps  
- **問:** サポートするチャネル幅は？  
  **答:** 最大 320 MHz  
- **問:** 導入された高次変調方式は？  
  **答:** 4096‑QAM  
- **問:** MLO とは？  
  **答:** Multi‑Link Operation。複数周波数帯の同時利用によるスループット＆冗長性向上  
- **問:** 低遅延化に寄与する OFDMA 拡張機能は？  
  **答:** Preamble Puncturing

---

## 2. ローカル5G（プライベート5G）
- **問:** 主なメリットは？  
  **答:** 専用帯域での安定通信、低遅延、高信頼、多数端末同時接続  
- **問:** URLLC とは？  
  **答:** Ultra‑Reliable Low‑Latency Communications  
- **問:** 導入手続きは？  
  **答:** 総務省への免許申請・基地局設置届出  
- **問:** Wi‑Fi 6/7 との使い分けポイントは？  
  **答:** 来訪者向けはコスト優位なWi‑Fi、業務ミッションクリティカルはローカル5G

---

## 3. Zero Trust（ゼロトラスト）
- **問:** 原則は？  
  **答:** Never trust, always verify（常に検証し、決して信用しない）  
- **問:** マイクロセグメンテーションとは？  
  **答:** ネットワークを細かく分割して通信をきめ細かく制御する手法  
- **問:** MFA の役割は？  
  **答:** 複数認証要素によるID認証の強化  
- **問:** Continuous Authentication とは？  
  **答:** アクセス後も継続的にユーザ／端末状態を検証する仕組み

---

## 4. SASE（Secure Access Service Edge）
- **問:** 構成要素３つは？  
  **答:** SD‑WAN、SWG（安全なWebゲートウェイ）、CASB（クラウドアクセスブローカー）  
- **問:** FWaaS とは？  
  **答:** Firewall as a Service（クラウド型ファイアウォール）  
- **問:** メリットは？  
  **答:** 拠点・ユーザをクラウド経由で一元的にセキュア接続／管理  
- **問:** ZTNA の役割は？  
  **答:** アプリケーション単位でアクセス制御を行うゼロトラスト型ネットワークアクセス

---

## 5. QUIC（HTTP/3）
- **問:** 使用するトランスポート層プロトコルは？  
  **答:** UDP  
- **問:** ヘッドオブラインブロッキング対策は？  
  **答:** 独立した複数ストリームで遅延影響を局所化  
- **問:** 0‑RTT ハンドシェイクの利点は？  
  **答:** 再接続時の往復遅延を削減  
- **問:** 統合暗号化方式は？  
  **答:** TLS 1.3

---

## 6. クラウドネットワーキング（ハイブリッド／マルチクラウド）
- **問:** 専用線接続サービスの例は？  
  **答:** AWS Direct Connect、Azure ExpressRoute  
- **問:** インターネットVPN と専用線の違いは？  
  **答:** VPN はコスト低・拠点数多向き、専用線は帯域保証／低遅延向き  
- **問:** マルチクラウド間ルーティングの手法は？  
  **答:** Transit‑Gateway（AWS）、Virtual WAN（Azure）  
- **問:** IaC が有効な理由は？  
  **答:** 設定の再現性・バージョン管理・自動展開の容易性

---

## 7. SD‑WAN
- **問:** コントロールプレーンとデータプレーンの関係は？  
  **答:** コントローラが一元管理し、拠点機器がトンネルでデータ転送  
- **問:** 動的経路選択に使う指標は？  
  **答:** 遅延、ジッタ、パケットロス率  
- **問:** アプリ優先制御を実現する要素は？  
  **答:** DPI（Deep Packet Inspection）  
- **問:** ゼロタッチプロビジョニングの利点は？  
  **答:** 拠点展開時の設定工数を大幅に削減

---

## 8. オブザーバビリティ（可観測性）
- **問:** 三本柱は？  
  **答:** メトリクス、ログ、トレース  
- **問:** 分散トレーシングの代表規格は？  
  **答:** OpenTelemetry  
- **問:** ストリーミングTelemetry とは？  
  **答:** 機器がリアルタイムにテレメトリデータを配信する仕組み  
- **問:** AIOps の寄与点は？  
  **答:** AIによる大量データの自動分析・異常検知

---

## 9. コンテナネットワーク＆サービスメッシュ
- **問:** CNI プラグイン例は？  
  **答:** Flannel（VXLAN）、Calico（BGP）  
- **問:** Sidecar プロキシの代表は？  
  **答:** Envoy  
- **問:** East‑West トラフィック とは？  
  **答:** クラスタ内（サービス間）の内部通信  
- **問:** NetworkPolicy の役割は？  
  **答:** Pod間通信のACL（アクセス制御）を宣言的に定義

---

## 10. ネットワーク仮想化（VXLAN/EVPN・NFV）
- **問:** VXLAN の VNID が表すものは？  
  **答:** 仮想ネットワーク識別子（最大16Mセグメント）  
- **問:** EVPN のコントロールプレーンは？  
  **答:** BGP（EVPN Address Family）  
- **問:** VNF とは？  
  **答:** Virtual Network Function（仮想ネットワーク機能）  
- **問:** MANO の役割は？  
  **答:** NFV の管理・編成・オーケストレーション

---

以上を技術ブログにコピペしていただくと、読みやすく整理された「一問一答キーワード集」として活用できます。試験対策から日々の学び直しまで、ぜひお役立てください！
【廃止】Data Standardization Superbadge Unit



https://trailhead.salesforce.com/content/learn/superbadges/superbadge_data_standardization_sbu

+ ロールアップ サマリー フィールドを構築して、データの精度とレポートを改善します。
+ ルックアップ フィルターを構成および更新して、ユーザー エクスペリエンスを向上させ、データ品質を強化します。
+ ピックリストを使用して、使いやすさを向上させ、データ入力を標準化します。
+ 複数選択ピックリストの欠点を説明し、代替ソリューションを構築します。


# 主要な機会データを表示する

各アカウントの重要な商談データを表示するようにソリューションを構成します。


:::note alert
We can't find the Won_Opp_Revenue field with the expected field settings. Make sure it has both a description and help text populated.

期待されるフィールド設定のWon_Opp_Revenueフィールドが見つかりません。説明とヘルプテキストの両方が入力されていることを確認してください。
:::

:::note alert
We can't find the Open_Opp_Expected_Revenue field with the expected field settings. Make sure it has both a description and help text populated.

:::

:::note alert
We can't find the expected updates to the Account Layout.
:::


# 誤ったレコード関係に対処する

ビジネス要件に基づいて正しいレコード関係を適用するソリューションを構築します。


:::note alert
We can't find the expected filter settings for the Primary Campaign Source field on the Opportunity object.


商談オブジェクトのプライマリキャンペーンソースフィールドに必要なフィルター設定が見つかりません。
:::

:::note alert
We can't find the expected filter settings for the Asset field on the Case object.

:::


# 地域とサブ地域を標準化する

オブジェクト間で再利用できるソリューションを使用して、リージョンとサブリージョンのデータを標準化します。

:::note alert
We can't find the Region picklist that can be used across objects with the expected values. Make sure the solution has a description.


複数のオブジェクトで使用できる、期待される値を持つ「地域」選択リストが見つかりません。ソリューションに説明があることを確認してください。
:::

グローバル選択リストにも説明がいるとは...

:::note alert
We can't find the expected field dependency based on the business requirements.
:::

:::note alert
We can't find the expected dependency for the Middle East and North Africa region.
:::



# コンサルティングパートナー向けの提供サービスを表示

各アカウントに複数のサービスを表示できるソリューションを構築してください。このソリューションでは、提供されるサービスの種類を明確に表示する必要があります。

:::note alert
We can't find the expected Offered_Service solution.


期待される Offered_Service ソリューションが見つかりません。
:::

:::note alert
We can't find the expected Account__c relationship for the Offered Service object. Make sure each offered service record has a related account and that the relationship has both a description and help text populated.

Offered Service オブジェクトに期待される Account__c リレーションが見つかりません。各 Offered Service レコードに関連アカウントが設定されていること、およびリレーションに説明とヘルプテキストが入力されていることを確認してください。
:::

また説明がいるのか、クソくらえだな。


::::note alert
We can't find the Service_Type__c field with the expected settings. Make sure the field has both a description and help text populated.


期待される設定のService_Type__cフィールドが見つかりません。フィールドに説明とヘルプテキストが入力されていることを確認してください。
:::


::::note alert
We can't find the Offered Services related list on the Account object with the expected settings.
:::


これを使えと言う事らしいけど... 確かにレポートはこの方法がよさそうですが余計にオブジェクトがいるのはお金がかかるな。

https://admin.salesforce.com/blog/2023/alternatives-to-a-multi-select-picklist
アンゾフの成長マトリクスとは

## アンゾフの成長マトリクス
アンゾフの成長マトリクスとは、どのような「製品」をどの「市場」に投入すれば事業を成長させられるかを検討する際に用いられる手法である。

・既存市場に既存製品
⇒**市場浸透**

・既存市場に新規製品
⇒**製品開発**

・新規市場に既存製品
⇒**市場開発**

・新規市場に新規製品
⇒**多角化**
venvについての解説

この記事では venv についての解説と Windows環境での利用方法について説明しています。



## venvとは
venv はプロジェクトごとに独立した Python の実行環境（仮想環境）を作成するための標準ツールです。仮想環境を使うことで、システム全体のPython環境とは切り離して、特定プロジェクト専用のパッケージを管理できます。Python 3.3以降に標準ライブラリとしてPython本体に含まれています。



## 仮想環境について
「仮想環境」と呼ぶ理由は **論理的に独立したPythonの環境** を複数作り出すことができるためこのように呼びます。この環境は物理的に別の Python を用意するのではなく、あくまでソフトウェア的に分離された空間を作るため「仮想（virtual）」と呼ばれます。仮想環境ごとにPython本体やライブラリ、モジュールなどを独立して管理できるため、システム全体の環境や他のプロジェクトに影響を与えずに作業できます。



## venvで分離されるもの
venvで分離される主なものは **Pythonパッケージ（ライブラリ）** とそれらの依存関係です。

venvで作成したPythonの仮想環境には、その環境専用のディレクトリが作られ、pipでインストールしたパッケージはこのディレクトリにのみ反映されます。これにより、グローバル（システム全体）のPython環境とは独立してパッケージを管理できます。

プロジェクトごとに異なるパッケージやバージョンを使いたい場合でも、他のプロジェクトやシステム全体の環境に影響を与えません。

仮想環境ごとに **Pythonの実行ファイル（インタプリタ）** もコピーまたはリンクされるため、その仮想環境内でPythonコマンドを実行すると、環境専用のPython実行ファイルが使われます。

### 分離されるもの	
- pipでインストールしたパッケージ
- 依存関係のバージョン管理
- Python実行ファイル

### 分離されないもの
- システム全体のPython本体
- OSの環境変数やPATH
- システム全体のパッケージ



## 基本的な使い方
PowerShell でコマンド入力して操作します。

### 仮想環境の作成
仮想環境を作成するフォルダを指定してコマンドを実行します。
`C:\Projects\Project1\venv`に作成する場合は以下のようにします。
```
python -m venv C:\Projects\Project1\venv
```
指定した場所に仮想環境が作成されます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4063083/fa8392ac-d83d-42fc-a587-860682589b12.png" width=80%>

### 仮想環境の削除
仮想環境のフォルダを削除します。


### 仮想環境のアクティブ化
仮想環境内の`\scripts\Activate.ps1`ファイルを実行します。
```
C:\Projects\Project1\venv\Scripts\Activate.ps1
```
仮想環境がアクティブになるとプロンプトの先頭に仮想環境名が表示されます。
```
(venv) PS C:\Users\ユーザ名>
```

### アクティブ化の解除
仮想環境がアクティブな状態で`deactivate`コマンドを実行します。
```
(venv) PS C:\Users\ユーザ名> deactivate
```
仮想環境のアクティブ化が解除されプロンプトの先頭の仮想環境名が無くなります。


### パッケージのインストール
仮想環境をアクティブにした状態でパッケージをインストールすると、そのパッケージは仮想環境内だけにインストールされます。
```
(venv) PS C:\Users\ユーザ名> pip install requests
```
仮想環境内の`\lib\site-packages`フォルダにパッケージがインストールされます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4063083/5bc790fc-d012-4eb0-853f-5fd243d71f1a.png" width=80%>

インストールされているパッケージを確認します。
```
(venv) PS C:\Users\ユーザ名> pip list
Package            Version
------------------ ---------
certifi            2025.1.31
charset-normalizer 3.4.1
idna               3.10
pip                22.3
requests           2.32.3
setuptools         65.5.0
urllib3            2.4.0
```
requests パッケージとその他依存関係を持つパッケージがインストールされていることが確認できます。

仮想環境のアクティブ化を解除してインストールされているパッケージを確認します。
```
(venv) PS C:\Users\ユーザ名> deactivate
PS C:\Users\ユーザ名> pip list
Package    Version
---------- -------
pip        22.3
setuptools 65.5.0
```
仮想環境にインストールした requests パッケージはグローバル環境にインストールされていないことが確認できます。
「検索ボックスに入力した文字列」と一致する「ギャラリーコントロール内の文字列」をハイライトする機能

ギャラリーコントロールの項目が検索ボックス内の文字列と一致した場合、その文字列をハイライトする機能に関しての共有です。

私は非ITエンジニアの市民開発者なので、おそらく難しい言葉を使ってないと(自分では)思っているので気軽に読んで頂ければと思います。

その上でどなたかのお役に立てば幸いです。

# 1. 環境
手元に下記のようなShareppoint List, PowerApps(キャンバス)がある状況とします。

**Sharepoint List** (データソース名 "DummyDB")
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3343332/69be42c5-902b-4aac-80fb-9e9b7c0e2e1c.png)


**PowerApps** (上記SharepointListを元に生成したものに少し手を加えたもの)
・**機能**：左側カラム上部の「検索」にワード入れると人がソートされ、選択されたアイテムの詳細が画面の右側に表示されるApps。人材管理や資産管理などに使える想定。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3343332/8442d09d-9732-4e43-86ff-cab65183aa7f.png)

# 2. 実例
下記のように、検索ボックスに文字を打つとその文字の部分をハイライトする機能です。
以降にこの機能についての解説を述べてます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3343332/c4e52957-6d71-45f8-9392-528ff470a848.png)

※現状大文字・小文字を区別せずハイライトする手段がなさそうなので今回はその前提の機能の解説です。なおギャラリーコントロールのフィルター自体は大文字・小文字を区別しないので安心してください。

# 3. 解説 - HTMLテキストラベルとその設定
この機能を利用する際はギャラリーコントロール内に通常の**テキストラベル**ではなく、**HTMLラベル**を配置します。
今回の例では下記の3つのHTMLラベルがギャラリーコントロール内に配置されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3343332/5ebdba90-d0d1-4762-9f84-5fb31bb42d08.png)

**検索ボックスのテキスト入力ラベル名を"SearchInput1"とした場合**、例えばName(名前)のHTMLラベルのHtmlTextプロパティは下記のように記載されています。
※Name(名前)情報はSharepoint上"タイトル"カラムに入れているので、ThisItem.Titleという表現が出てきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3343332/03b33365-ab45-4607-8f42-81e3311b35bb.png)

この部分について解説すると下記のような感じです。
簡単にまとめると「HTMLラベル内文字列と検索文字列で一致してる箇所に、HTML の \<mark>タグをつける」ことをしています。
```
# 実例のコードの解説
HtmlText = Substitute('ギャラリーコントロール内のHTMLラベル内に表示されている文字列', '検索に利用されている文字列', "<mark>" & '検索に利用されている文字列' & "</mark>")

# もっとシンプルな解説
HtmlText = Substitute('HTMLラベル内文字列', 'ハイライトしたい文字列', "<mark> & 'ハイライトしたい文字列' & </mark>")
```

- **Substitute関数**：文字列の入れ替えをする関数 (実例だと"ThisItem.Title")
- **\<mark> ~ \</mark>**: HTMLのmark(ハイライトの表現をするタグ)
- **&**: 文字列の足し算の記号

これをギャラリーコントロール内の全部のHTMLラベルに設定すれば、すべての項目に対しハイライト機能を実装できます。(ギャラリーコントロールじゃなくても全然いいと思いますが)

またタグを\<mark>以外にすることもできるので、自身のしたい表現に合わせてタグを調整してみるといいと思います

# 4.おわりに
関連する記事もいくつかあるので、興味あればこちらも覗いてみて下さい。

https://qiita.com/_Sasaki_/items/518d930a5ba548d060a1

https://qiita.com/_Sasaki_/items/2f30188ed66f91c5dd08