OmniAICreator/Qiita-1.07M huggingface dataset:
🔊 AI音波通信の未来！🚀 ggwaveを活用した次世代エージェント間コミュニケーション 🤖📡

# 📡 ggwaveライブラリの重要性とAI間の高速コミュニケーションへの応用 🚀
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3917980/b9a3baa7-e8e8-42f9-97ad-cb9ffe666217.png)

## 1️⃣ はじめに 🧐

近年、AIエージェントが様々な分野で活用されるようになり、**AI同士のコミュニケーションの効率化**が求められるようになっています。特に、カスタマーサポート、ホテル予約、電話対応などの自動化が進む中、**AIエージェント間のデータのやり取りを高速化する技術**が不可欠になってきました。💡

そこで、**AntonとBoris**という開発者が、AI同士の通話時に高速にデータをやり取りするための技術として**ggwaveライブラリ**を活用し、新たなソリューション「**Gibberlink**」を開発しました。🔧

本記事では、**ggwaveの基本、重要性、AI間通信への応用、およびGibberlinkがどのようにこの課題を解決するのか**について詳しく解説していきます。📖✨

---

## 2️⃣ ggwaveとは？📢

**ggwave**は、音波を利用してデバイス間で小容量のデータを送受信できる軽量なライブラリです。主に、**インターネット接続やWi-Fi、Bluetoothを使わずにデータをやり取りするための手段**として利用されます。📡

💡 **主な特徴：**
- **音波によるデータ伝送**（Wi-Fi不要）
- **低遅延でリアルタイム通信が可能**
- **オープンソースでカスタマイズが容易**
- **IoTデバイスやAIエージェント間のデータ共有に最適**

💡 **なぜ音波なのか？**
Wi-FiやBluetoothを介さずにデータ通信を行うことで、**よりセキュアで迅速なデータ交換**が可能になります。音波は物理的な空間を超えて瞬時に伝播し、特に**音声ベースのAI通信**には理想的な手段となります。🎤🎧

---

## 3️⃣ ggwaveの活用事例 🚀

ggwaveは、すでに様々な分野で活用されています。

✅ **IoTデバイス間のデータ共有**
✅ **QRコード不要の認証システム**
✅ **オフライン環境でのデータ通信**
✅ **イベントやコンサートでの参加者認証**
✅ **AIエージェント間のリアルタイム通信**

その中でも特に注目されているのが、**AIエージェント同士の音波通信**による新たなソリューションです。🔊🤖

---

## 4️⃣ AIエージェント間の高速通信とggwave 📞🤖

AIの活用が進むにつれ、**AI同士が直接コミュニケーションをとる場面**が増えています。

💡 **課題:**
- **AIエージェント同士の会話の遅延**（インターネットベースでは応答にタイムラグが発生）
- **音声認識の誤解釈**（自然言語処理の誤認識による問題）
- **通信コストの増加**（クラウドAPIの使用コスト）

そこで、**ggwaveを活用した「Gibberlink」**が開発されました。🔧

📡 **Gibberlinkとは？**
Gibberlinkは、AI同士が電話を介して会話をする際に、**ggwaveを用いた音波通信を活用し、データのやり取りをスムーズにするシステム**です。

🔹 **Gibberlinkの仕組み:**
1. **AIエージェントが電話を発信または受信**
2. **ggwaveを用いて音波経由でデータを送信**
3. **相手のAIエージェントが音波をデコードし、正確に情報を解釈**
4. **リアルタイムで情報を送受信し、会話の遅延を最小限に抑える**

🎯 **メリット:**
✅ **低遅延**：音波によるダイレクト通信で応答速度向上
✅ **コスト削減**：APIコールを減らし、クラウド処理のコスト削減
✅ **高精度**：音波データを直接やり取りすることで誤認識を防ぐ
✅ **リアルタイム性**：AIのやり取りがスムーズになり、ユーザー体験が向上

---

## 5️⃣ ggwave + AIの実装方法 🛠️

実際にPythonで**ggwaveを用いたAIエージェント間通信のサンプル**を実装してみましょう！

### **1. ggwaveのインストール**
```bash
pip install ggwave
```

### **2. AIエージェントから音波を送信**
```python
import ggwave

message = "予約確認：12時にミーティング"
wave_data = ggwave.encode(message)

# wave_dataをスピーカーから再生
print("音波データ送信中...")
```

### **3. 受信AIエージェントが音波を解析**
```python
import ggwave

received_wave_data = ...  # マイクで受信した音波データ
message = ggwave.decode(received_wave_data)

print("受信メッセージ:", message)
```

このように、**AIエージェント同士が音波を介してリアルタイムで情報を交換**できるようになります！📡🔊

---

## 6️⃣ まとめ 🎯

✅ **ggwaveは音波を用いたデータ通信ライブラリで、Wi-FiやBluetoothを使わずにデータのやり取りが可能！**
✅ **GibberlinkはAI同士の通話を高速化し、通信コストを削減する画期的なソリューション！**
✅ **Pythonを使えば、簡単にAI間のリアルタイム音波通信を実装可能！**

今後、**ggwaveとAIの組み合わせ**によって、さらなる**高速・低遅延なAIエージェントの通信**が実現されるでしょう。🚀

🎙 **Gibberlinkのような音波通信技術は、今後どのように進化すると思いますか？ ぜひコメントで意見を聞かせてください！😊**
キャプチャ演算子

# キャプチャ演算子とは？　(公式ドキュメント引用)
> キャプチャ演算子（&）を使用したEnum
ElixirのEnumモジュール内の多くの関数は、渡されるEnum型のオブジェクトを処理するための引数として無名関数を取ります。 これらの無名関数は、多くの場合、キャプチャ演算子（&）を使用して省略形で記述されることが多いです。

> Enum.map([1,2,3], fn number -> number + 3 end)
[4, 5, 6]

を

> Enum.map([1,2,3], &(&1 + 3))
[4, 5, 6]

として記述することができる。

https://elixirschool.com/ja/lessons/basics/enum#%E7%84%A1%E5%90%8D%E9%96%A2%E6%95%B0%E3%81%A7%E3%81%AE%E3%82%AD%E3%83%A3%E3%83%97%E3%83%81%E3%83%A3%E6%BC%94%E7%AE%97%E5%AD%90%E3%81%AE%E4%BD%BF%E7%94%A8-11

# 考察
アンパサンドで続けられた関数に対してその前（今回のケースでは第一引数のリスト）を渡して機能を処理することができるのだと考えられる。
fnを無駄に書くことを減らせれるので理解することで可読性を向上させれる効果が期待できそうである。

# 終わりに
&を調べる際に『elixir アンパサンド』で調べると日本語の記事がヒットしなかった。
またelixirの公式に検索ワードで『&』を入れてもヒットしなかったため教材を引っ張ってきてやっと理解した。
こういった手間が無くて済むように当記事を書いた。
『elixir アンパサンド』で調べた際に公式ドキュメントへと行きつく導線となれば幸いです。
栄養バランスの知識習得と健康管理アプリ開発

## はじめに
本記事では、卒業研究として取り組んだ**健康管理と食事メニュー提案アプリケーションの開発**を通じて、栄養学に関する知識を深めた過程をまとめます。特に、**栄養価計算の方法や健康的な食生活のための食材選び**に関する学習内容を整理し、今後の食生活改善にどのように活用できるかを考察します。

## 背景
一人暮らしを始めたことで、食事の栄養バランスが崩れ、**高脂質な食事や野菜不足が続いた結果、風邪をひきやすくなり、体重増加などの健康リスクが顕在化**しました。また、パートナーは**貧血気味であるため、適切な栄養素の摂取が必要**でした。しかし、既存の食事管理アプリでは詳細な栄養バランスの確認ができず、適切な食事選択をサポートする機能が不足していました。

これらの課題を解決するために、
- **栄養バランスを可視化するアプリの開発**
- **栄養学の知識習得**

を研究の目的としました。

## 研究の目的
### 1. アプリ開発による食事の可視化
食事の栄養バランスを管理するため、以下の機能を持つアプリを開発しました。
- **食事画像から栄養価計算を行う機能**
- **摂取栄養素をグラフで可視化する機能**
- **栄養バランスを調整するメニュー提案機能**
- **貧血改善や低脂質などのカテゴリ別メニュー提案機能**

### 2. 栄養学の知識習得
長期的な健康維持のためには、栄養バランスの知識が不可欠です。本研究では、
- **日本食品標準成分表を基にした栄養価計算の方法**
- **食材と分量から栄養素を算出する方法**
- **各栄養素の推奨摂取量と健康リスクの関係**
- **生活習慣病（糖尿病、高血圧、動脈硬化）と食事の関連性**

について学習し、それらを活用した食事の選び方を考察しました。

## 学習した内容
### 1. 栄養価計算の仕組み
日本食品標準成分表を基に、食材ごとの栄養価を算出しました。**Google Cloud Vision API** を利用して食事画像から食材を解析し、**OpenAI API** にデータを送信することで、カロリーや主要栄養素（タンパク質、脂質、炭水化物、ビタミン、ミネラル）の値を計算しました。

### 2. 栄養素の基準値と健康リスク
各栄養素の過不足は、健康に大きな影響を与えます。
- **鉄分不足 → 貧血、疲労感**
- **脂質過多 → 生活習慣病（肥満、動脈硬化）**
- **食物繊維不足 → 便秘、腸内環境の悪化**

適切な栄養素の摂取バランスを保つことで、将来的な健康リスクを軽減できることが分かりました。

### 3. 食材選びの工夫
特定の栄養素を補うための食材を学びました。
- **鉄分を多く含む食材：レバー、ほうれん草、赤身肉**
- **低脂質で高タンパクな食材：鶏むね肉、大豆製品、白身魚**
- **食物繊維が豊富な食材：玄米、野菜、豆類**

この知識を活かし、日々の食事で意識的に食材を選ぶことが重要であると考えました。

## 今後の活用
今回の研究を通じて得た栄養学の知識を、**自身の食生活に活かすことで、長期的な健康維持を目指します**。具体的には、
- **食材の栄養価を意識した買い物や献立作成**
- **栄養バランスを考慮した食事の記録と振り返り**
- **健康状態に応じた食事改善（脂質コントロールや鉄分補給）**

を行い、無理なく継続できる形で食習慣を整えていきたいと考えています。

## まとめ
本研究では、**食事管理アプリの開発**と**栄養学の学習**を通じて、健康的な食生活の実現を目指しました。特に、
- **栄養バランスの可視化の重要性**
- **食材選びや栄養素の摂取バランスの知識**
- **日々の食生活への実践的な応用**

を学ぶことができました。今後も、この知識を活用し、健康維持と食生活の充実を両立させるための工夫を続けていきます。

---

### 📌 関連リンク
- [日本食品標準成分表（文部科学省）](https://www.mext.go.jp/a_menu/syokuhinseibun/mext_00001.html)
- [OpenAI API 公式ドキュメント](https://platform.openai.com/)
- [Google Cloud Vision API 公式サイト](https://cloud.google.com/vision)

### ✏️ 参考文献
- 日本食品標準成分表（八訂）増補2023年 文部科学省
- OpenAI API公式ドキュメント
- ChatGPT - 料理カロリー計算士 (OpenAI)
個人的備忘録：Windowsのコマンドプロンプト（cmd）を使って画像ファイルを検索する方法

## はじめに

Windowsのコマンドプロンプト（cmd）を使って、パソコン内のすべての写真（画像ファイル）を検索する方法を紹介します。

代表的な方法として、`dir` コマンド、`where` コマンド、PowerShell を活用する方法があります。

## 書こうと思ったきっかけ

エクスプローラーで画像を検索すると時間がかかり、不便に感じていましたが、試しにコマンドを使ってみたところ、驚くほど速く検索できて感動しました。

この便利さを多くの人に知ってもらいたくて、まとめることにしました。

## 1. `dir` コマンドを使う方法
`dir` コマンドを使うと、指定したフォルダ内のファイルを検索できます。画像ファイル（jpg, png, gif など）を検索する場合は、以下のコマンドを実行してください。

### Cドライブ全体を検索する場合
```cmd
 dir C:\*.jpg C:\*.png C:\*.gif C:\*.bmp C:\*.jpeg /s /a /b
```
**このコマンドの意味**
- `C:\*.jpg C:\*.png ...` → Cドライブ内の画像ファイルを対象にする
- `/s` → サブフォルダも含めて検索
- `/a` → 隠しファイルも含める
- `/b` → ファイル名のみを表示

### Dドライブも検索する場合
```cmd
 dir D:\*.jpg D:\*.png D:\*.gif D:\*.bmp D:\*.jpeg /s /a /b
```
※他のドライブも同様の方法で検索できます。

## 2. `where` コマンドを使う方法
`where` コマンドは通常、プログラムの検索に使われますが、`/r` オプションを使うことで、フォルダ内の特定の拡張子を検索できます。

```cmd
where /r C:\ *.jpg *.png *.gif *.bmp *.jpeg
```
**このコマンドの意味**
- `/r C:\` → Cドライブ内のすべてのフォルダを対象にする
- `*.jpg *.png ...` → 指定した拡張子のファイルを検索する

## 3. PowerShell を使う方法（より高機能）
WindowsのコマンドプロンプトよりもPowerShellを使うと、より強力な検索が可能です。

### 画像ファイルを検索する
PowerShellを開いて以下のコマンドを実行します。
```powershell
Get-ChildItem -Path C:\ -Include *.jpg, *.png, *.gif, *.bmp, *.jpeg -Recurse -ErrorAction SilentlyContinue
```
**このコマンドの意味**
- `Get-ChildItem` → 指定したフォルダ内のファイルを一覧取得
- `-Path C:\` → Cドライブ内を検索
- `-Include *.jpg, *.png, *.gif, *.bmp, *.jpeg` → 指定の拡張子を含むファイルを検索
- `-Recurse` → サブフォルダも含める
- `-ErrorAction SilentlyContinue` → 権限エラーが出ても無視する

## 4. エクスプローラーの検索を使う方法
コマンドを使わずに検索したい場合は、Windowsのエクスプローラーを活用できます。

### 手順
1. エクスプローラーを開く
2. `PC` や `Cドライブ` を開く
3. 右上の検索バーに以下の文字列を入力
   ```
   *.jpg OR *.png OR *.gif OR *.bmp OR *.jpeg
   ```
4. 検索結果が出るのを待つ

## どの方法を使うべき？
| 方法 | 特徴 |
|------|------|
| `dir` コマンド | シンプルに検索したい場合におすすめ |
| `where` コマンド | より速く検索したい場合におすすめ |
| PowerShell | 詳細な情報を取得したい場合におすすめ |
| エクスプローラーの検索 | コマンドに慣れていない人におすすめ |

やりたいことや環境に応じて適切な方法を選んでください！
プログラミングど素人がAIに聞きながら、2週間でGASで顧客管理システムを作った話

# はじめに

AIがヤバい、という話です。
（素人からしたら）

僕は最近まで、プログラミングのプの字も知らないド素人でした。

初心者向けの解説本を読んでも
「そもそも「変数」ってなんぞや。もっと一般人向けの用語でイチから解説せーや！」
ってテンパるレベル。

ところが、ClaudeとGeminiの課金版を駆使することで

実働2週間もかからずに

仕事で管理しているお客さんに対して

スプレッドシート（以下スプシ）上の情報を読み取って

・自動で請求書をLINEとメールで送ったり

・任意で好きな内容を複数人に送ったり

・客がLINE公式アカウントに送ってきた内容に対して、設定した分数だけ遅延させてから自動応答するような、特殊自動応答botを作ったり


簡単な顧客リレーションシップなら問題ないレベルまで作り込めたので
その過程を共有します。


要するに、AIやべー。


やりたいことを分解して、AIに「これこれこういうことしたい」って順序立てて問い合わせさえできれば

誰でも駆け出しプログラマーくらいになれる時代が来たのかな。
地殻変動起きてるな、っていう話です。


もちろん
AIも万能じゃないから、なんでその指示をそう解釈すんねんアホか、みたいな場面は結構あるから
初心者は多少は悪戦苦闘しますね。

でも、作っていくうちに「プログラミングのお作法」が、自然と少しは身につくので
「ああ、この関数の内容だけ教示データにしたから、AIは前の関数から渡される引数の内容を無視してコード書いちゃったんだな」
とか
AIを上手く調教するコツとかも分かってきたりします。

# 何を作ったのか
プログラマーの諸先輩方から見たら
たぶん、鼻で笑われるレベルの簡単なものです苦笑

ただ、初心者がAIに聞きながら作り、それによって仕事が自動化されて余暇を捻出できた
ということの意義は大きいと思うので
恥ずかしさもありますが
堂々と載せていきます。


## ベースとなる、コンテナバインドのスプシのイメージ

![スクリーンショット_2025-02-25_16_32_21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325814/5f006476-24df-449b-8f5c-7d485834add0.png)


1行毎に、各顧客に関する情報が全網羅された、管理シートみたいなものは以前から作っていた。

ここに顧客属性や、顧客の行動によるフラグを立て、次回請求日などを手動で入れて
毎回スプシで手動フィルタリングして
「この人には次このアクションをしないと」みたいなことを、全部人力でやっていたので
一部自動化したらラクだろうな、と、ずっと思っていた。

## この↑「管理シート」の情報をベースとして、各GAS機能を動かすための補助シートを、同じスプシID内に作成していった

![スクリーンショット 2025-02-25 17.22.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325814/54f6b64a-be9f-4506-bbed-db2b75c2632f.png)

細かい機能は後述しますが
送信内容とか、「いつ送るか」とかを設定する、補助シートの一例

# 書いたコードたち

## メール関連

### ・請求日の自動リマインドbot（メールバージョン）

https://qiita.com/sh102/items/f4faae0269ac31f95229

### ・複数人に同じ内容を同時送信したい時に、BCC使わずにToで送れるやつ

即時送信、予約送信、両方対応

>記事執筆中


## LINE関連

### ・請求日の自動リマインドbot（LINEバージョン）
>記事執筆中

### ・複数人に同じ内容を同時送信するやつ
>記事執筆中

本来これは、LINE公式アカウントのコンソール上で、チャットタグでオーディエンスを作ればいいだけの話でした。

ところが
2025年3月以降、無料プランだと、1人につき1つのタグしかつけられないように仕様が変わるので
●月に購入した人、商品Aを買った人、みたいに別軸で顧客属性を分けた一斉送信が不可能になります。

そこで急遽
スプシの管理シートで、各顧客に対して、いろんな切り口でチャットタグ代わりのフラグを立てて
それに該当した顧客に、柔軟に一斉送信する機能を作る必要が出てきました。
（というか、このLINE社の仕様変更告知に触発されて、GAS作らなアカン、とケツに火がついた）

やり取りするお客さんが毎回数百人とかいれば、チャットProオプション加入一択でしょうけど
自分みたいに、時期によっては10人くらいしか相手しない、みたいな場合は、毎月3,000円はもったいないので……。

### ・doPost関連
https://qiita.com/sh102/items/e46d7f47137dbd72a974

顧客からフォローされた、何かしらのメッセージを受け取った、というイベント発生時に
・自動でユーザーIDを「管理シート」に記入したり
・自動応答（遅延応答もできる）させたり
といった機能を作成しました。


# 今後作りたいもの

## 簡易的なステップLINE機能
 
LINE公式のステップ機能はあまりに貧弱
LSTEPは高額すぎる
エルメ、UTAGEは微妙にカユイところに手が届かない
という状況下で

自分が思う「使いやすいステップ送信システム」を
作っていきたいと思っています。

ステップの予約送信とか、1分ごとにトリガー発火させると、何かしらのペナルティをGoogleから食らいそうなので
スプシの「設定シート」上に書いた送信時刻を読み取って、対応したトリガーを作る方向性かな……🤔
PyTorchのAMP (Automatic Mixed Precision) 入門

## はじめに

ディープラーニングモデルの学習では、高精度な計算が必要ですが、その分多くのメモリと計算時間を消費します。特に大規模なモデルを学習する際、この問題は顕著になります。PyTorchの**AMP (Automatic Mixed Precision)**は、この課題を解決するための強力なツールです。AMPを使うことで、精度をほとんど損なわずに、計算速度の向上とメモリ使用量の削減が可能になります。

本記事では、PyTorchのAMPの基本概念、導入方法、そして具体的なサンプルコードをご紹介します。

## AMP (Automatic Mixed Precision) とは？

AMPは、32ビット（FP32）と16ビット（FP16）の精度を自動的に切り替えて学習を行う手法です。これにより、次のような利点があります：

- **学習速度の向上**：16ビット浮動小数点数を使用することで、GPUの計算速度が向上します。
- **メモリ使用量の削減**：FP16を活用することで、より大きなバッチサイズやモデルが扱えるようになります。
- **精度の維持**：スケーリング技術を使って、精度の損失を最小限に抑えます。

## PyTorchでのAMPの導入

PyTorchでは、`torch.cuda.amp`モジュールを使用して簡単にAMPを導入できます。以下に、AMPを活用したサンプルコードを示します。

### サンプルコード："中野哲平" を学習する簡単なモデル

このサンプルでは、"中野哲平" という文字列を出力することを学習するシンプルなモデルをAMPを使って学習します。

```python
import torch
import torch.nn as nn
import torch.optim as optim
from torch.cuda.amp import autocast, GradScaler

# デバイス設定
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

# サンプルデータ
input_text = "中野哲平"
target = torch.tensor([ord(c) for c in input_text], dtype=torch.float32).unsqueeze(0).to(device)

# シンプルなモデル
class SimpleTextModel(nn.Module):
    def __init__(self, input_size, hidden_size, output_size):
        super(SimpleTextModel, self).__init__()
        self.fc1 = nn.Linear(input_size, hidden_size)
        self.relu = nn.ReLU()
        self.fc2 = nn.Linear(hidden_size, output_size)

    def forward(self, x):
        out = self.fc1(x)
        out = self.relu(out)
        out = self.fc2(out)
        return out

# ハイパーパラメータ
input_size = len(input_text)
hidden_size = 64
output_size = len(input_text)

# モデル、損失関数、最適化手法の設定
model = SimpleTextModel(input_size, hidden_size, output_size).to(device)
criterion = nn.MSELoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)

# AMP用のスケーラー
scaler = GradScaler()

# 学習ループ
epochs = 100
for epoch in range(epochs):
    optimizer.zero_grad()

    # Mixed Precisionでの学習
    with autocast():
        input_tensor = torch.randn(1, input_size).to(device)
        output = model(input_tensor)
        loss = criterion(output, target)

    # 勾配のスケーリング
    scaler.scale(loss).backward()
    scaler.step(optimizer)
    scaler.update()

    if (epoch + 1) % 10 == 0:
        print(f"Epoch [{epoch+1}/{epochs}], Loss: {loss.item():.4f}")

print("\n学習完了！\n")

# 結果の表示
with torch.no_grad():
    test_input = torch.randn(1, input_size).to(device)
    predicted = model(test_input)
    predicted_chars = [chr(int(c.item())) for c in predicted[0]]
    print("予測された文字列:", "".join(predicted_chars))
```

### コードのポイント

1. **`autocast()`**：
   - 自動的に適切な演算をFP16で実行します。
   - 精度が重要な演算はFP32のまま維持されます。

2. **`GradScaler`**：
   - 勾配のスケーリングを行い、FP16での勾配消失問題を防ぎます。
   - `scale()` と `update()` でスケールの適用と調整を行います。

3. **結果の解釈**：
   - 学習後にモデルから生成された出力を、文字列としてデコードしています。

## AMPを使った際の注意点

- **数値の安定性**：
  - AMPは計算速度とメモリ効率を向上させますが、場合によっては数値の不安定さが発生することがあります。`GradScaler`を正しく使用することで、この問題を軽減できます。

- **非対応のオペレーション**：
  - 一部のPyTorch演算はFP16に対応していない場合があります。その際、`autocast`の外で明示的にFP32を使用することができます。

## おわりに

PyTorchのAMPは、ディープラーニングモデルの学習を効率化するための強力なツールです。特に大規模なモデルやリソースが限られた環境での学習において、その効果は絶大です。今回のサンプルコードのような簡単なケースでも、AMPを導入するだけでメモリ使用量の削減や学習速度の向上が期待できます。

是非、あなたのプロジェクトにもAMPを導入して、その効果を実感してみてください！🚀
小説家になろうの新着の感想を消す方法

# はじめに
iPhoneのSafariブラウザで、
25年1月末頃に実装された小説家になろうの小説ページ下部の新着の感想を消す方法になります
![新着の感想](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/299114/7ac6a417-d73c-46b1-a1ee-32aa811db65b.png)

環境
iOS18.3.1


# 流れ
ストアから以下のアプリをダウンロード(無料)
Makeover - Custom CSS

https://apps.apple.com/jp/app/makeover-custom-css/id1602361167

ダウンロード後は
設定→アプリ→Safari→機能拡張→Makeover Custom CSSを有効にし、アクセス権を設定

小説家になろうの適当な小説ページを開き、画面端のあぁ(リーダーモード)を開き、
Makeoverを押します
![リーダーモード](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/299114/294374e7-225d-4b0c-a135-a7d8ee74ceb5.png)

Makeoverの画面を開いたら以下のコードを入力します
```
div [class="p-new-impression"]{
display: none !important;
}
```
![Makeover](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/299114/b7c787f9-5fbf-48f3-865f-5d82bf4ab6c6.png)
ページを再読み込みすると反映されます
[AWS AI Practitioner AIF-C01] の準備戦略。

# AWS認定AIプラクティショナー試験戦略

## 自己紹介
私は2024年に卒業し、日本の企業にAIエンジニアとして就職したインド人卒業生です。AWSの経験はあまりありませんが、クラウドベースのAIソリューションに関する知識を深めるためにAWS認定AIプラクティショナー試験を受験することにしました。

## 試験準備の流れ
- **開始日:** 2025年3月3日  
- **試験日:** 2025年3月24日  
- **スコア:** 813（合格）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4020756/8d232f79-ff5a-49c6-8993-5f49289346d8.png)

## 使用したリソース
1. **AWS無料PrepBuilderコース** – コンセプトの概要を学ぶのに最適なスタートポイント。
2. **Stephane MaarekのAWS AIプラクティショナーコース（Udemy）** – 詳細な解説と実践的な知識を提供。
   - このコースには**日本語字幕**が付いており、理解を深めるのに役立ちます。

## 試験準備の戦略
1. **試験ガイドの確認**  
   - 最初に試験のシラバスと各ドメインの配分を理解することから始めました。
   - ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4020756/9b572557-0068-44e4-9a5d-021974e8fe27.png)

   
2. **毎日の学習ルーチン**  
   - 毎日**最低2時間**の学習時間を確保。
   - ビデオ講義の視聴、ノート作成、クイズの実施を行う。

3. **コース完了と復習**
   - UdemyのStephane Maarekのコースを修了した後、AWS PrepBuilderコースを再度確認。
   - 模擬試験を受ける前に、理解度を確認。

4. **模擬試験の実施**  
   - 十分に準備ができたと感じたら、Stephane Maarekのコースに含まれる**模擬試験**を受験。

5. **重点的に学習すべき分野**  
   - **ドメイン3: 基盤モデルのアプリケーション（28%）**を最優先で学習。
   - 生成AI、基盤モデル、その応用に関する強固な理解を確立。

6. **出題傾向**  
   - **シナリオベース**の問題が多く、**プロンプティング、ファインチューニング、RAG**の適用に関する知識が求められる。
   - **Amazon Qに関する問題が3～4問**。
   - **さまざまなプロンプト攻撃の種類**を学習。
   - **SageMakerのサービスを深く学習**し、その機能を理解。

## 重要なポイント
- **継続的な学習が重要** – 定期的な学習セッションが効果的な理解につながる。
- **概念を理解することが大切** – AWS AIサービスや基盤モデルは単なる暗記ではなく、概念の理解が必要。
- **模擬試験が役立つ** – 試験のフォーマットに慣れ、自信をつけるのに効果的。

この戦略を実践することで、AWS認定AIプラクティショナー試験に813点で合格しました。これから受験する方々の参考になれば幸いです！
個人的備忘録：Application Load Balancer (ALB) のリスナーとルールの仕組みをまとめてみた

## はじめに

AWSのApplication Load Balancer（ALB）は、トラフィックをターゲットグループにルーティングするための重要なコンポーネントです。

本記事では、ALBのリスナーとルールについて詳しく解説します。

## 書こうと思った理由

AWS環境で負荷分散を行う際にALBを使用する機会が多く、リスナーとルールの設定を正しく理解していないと、適切なトラフィック制御ができません。

:::note warn
**特に、複数のサービスをホストする場合やHTTPSリダイレクトを実装する際には、ルールの使い方が重要になります。**
:::

そこで、ALBのリスナーとルールについて整理し、設定のポイントをまとめました。

## ALBのリスナーとは

リスナー（Listener）は、ALBが受信するトラフィックをどのように処理するかを決定するコンポーネントです。

https://dev.classmethod.jp/articles/elb-explanation-try/

リスナーには、プロトコルとポートを指定し、ルールを設定することでリクエストの振り分けを行います。

### リスナーの主な構成要素
1. **プロトコル**: HTTP または HTTPS
2. **ポート**: 80（HTTP）、443（HTTPS）など
3. **デフォルトアクション**: リクエストをどのターゲットグループに送るかのデフォルト動作

## ALBのルールとは

リスナーには複数のルール（Rules）を設定でき、これによりトラフィックを細かく制御できます。ルールは以下の要素で構成されます。

https://dev.classmethod.jp/articles/alb-path-and-ip-based-restriction/

### ルールの構成要素
- **条件（Conditions）**: 特定のリクエストを識別するための条件（例: パス、ホストヘッダー、HTTPヘッダーなど）
- **アクション（Actions）**: 条件を満たしたリクエストに対する処理（例: 転送、リダイレクト、固定レスポンス）
- **優先度（Priority）**: ルールの適用順（数値が小さいほど優先）

## ルールの具体例

### 例1: パスベースルーティング
```
条件: パスが `/api/*`
アクション: API用のターゲットグループに転送
```

### 例2: ホストベースルーティング
```
条件: ホストが `example.com`
アクション: `example.com` 専用のターゲットグループに転送
```

### 例3: HTTP to HTTPS リダイレクト
```
条件: HTTP リクエスト
アクション: HTTPS にリダイレクト
```

## ALBのルール設定方法

### AWS マネジメントコンソールを使用する場合
1. **EC2 ダッシュボード** > **ロードバランサー** に移動
2. 対象の ALB を選択し、**リスナー** タブを開く
3. **ルールを編集** をクリックし、新しいルールを追加
4. 条件とアクションを設定し、保存

### AWS CLI を使用する場合
```sh
aws elbv2 create-rule \
  --listener-arn <リスナーのARN> \
  --priority 10 \
  --conditions '[{"Field": "path-pattern", "Values": ["/api/*"]}]' \
  --actions '[{"Type": "forward", "TargetGroupArn": "<ターゲットグループのARN>"}]'
```

## まとめ

- **リスナーはALBのエントリーポイント**であり、プロトコルやポートを決定する
- **ルールは細かいルーティングを実現**するために使用される
- **AWSマネジメントコンソールやCLIで簡単に設定可能**

***ALBのリスナーとルールを活用することで、より柔軟なトラフィック管理が可能になります。***

用途に応じて適切なルールを設定し、効率的なシステム運用を目指しましょう。
DifyとLLMを用いてgitlabの自動コード・レビューを作成しましょう(1)。

開発現場ではチーム単位でMRなどが発生の時人間がコードをレビューします。普段は経歴者が導いて行うので意味があるレビュー情報が十分に出ます。

でもブートキャンプなどの教育機関でチームメンバがみんな初心者なので、お互いにコード・レビューをしても無意味な情報ばかり交換される可能性が高いです。

意味があるレビューのため外部からのレビューが必要しました。そのため、他の教育機関ではパートタイマーを雇いてコード・レビューをさせます。僕はその役割をGPTみたいなLLMに任せるのがいいじゃないかと思いました。AIの狂風が吹いてるこの時期で充分に考えられるのではないでしょうか。

私が所属するブートキャンプで学生たちはgitlabでコードを管理します。だからgitlabでwebhookを設定しそれと連携されるサーバーを作ってそこから生成型AIに情報をわたして分析結果を受け取る形になります。

まずDIFYのフローの全体図は以下のようです。

![image-20250224134724467.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55902/60f45dff-9871-4b11-8228-a98e590a8b40.png)

一応「Start」ノードから見てみましょう。

![image-20250224142613177.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55902/b926f58a-4c42-49c0-9797-71704627091f.png)

“Start”ノードは五つの入力データをもらいます。

* Private_token : gitlabから発行されるAccess Token値です。
* prjid : MRなどイベントが発生するプロジェクトのIDです。
* siteurl : gitlabのサーバーURLです(例：https://examle.gitlab.com/)
* branch : 情報を取得するブランチです。
* state : どんな状態のMRを持ってくるかの情報です。(opened or closed)

次の段階でノード「**GetMRList**」をみましょう。
![image-20250224145125325.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55902/76d0bbc6-08a7-4bcb-881a-5aedad346223.png)

スクロールを下るとエラー・ブランチの設定が表示されてます。

GetMRListの特性は“コード”です。DifyはJavaScriptまたPython Scriptを支援します。ここでにpythonを使いました。

```python
import requests
import json


def main(prvtoken:str, prjid:str, siteurl:str, branch:str, state:str) -> dict:
	url = f"{siteurl}/api/v4/projects/{prjid}/merge_requests"
	headers = {"Private-Token": prvtoken}
	params = {
		"state": state,
		"target_branch": branch
	}
	response = requests.get(url, headers=headers, params=params)

	urlList = []

	if response.status_code == 200:
		mrs = response.json()

		# web_urlのみ洗い出し
		urls = [mr["web_url"] for mr in mrs if "web_url" in mr]

		# 結果出力
		for url in urls:
			urlList.append(url)
	else:
		print("Fail to call API")


	return {
		"results": urlList,
		"count" : len(urlList)
	}
```

入力データは前のノードからもらったデータをそのままもらいます。これをgitlab APIで伝えるURLとParam形で加工してrequestをGETで投げて返事をもらいます。返事の中で我々が必要なのはMRのURLので、このURLのみ洗い出してDictionaryで返す仕組みです。入力データ五つと出力変数二つをノードに設定します。

エラーが発生する時エラー対応方法もノードで決められます。ここには“枝”を作って成功枝と失敗枝で分けました。エラーの時では“End”ノードに外してエラー・コードまたメッセージを出力します。成功すれば次のノードである“REPEAT”に繋がります。以下のイメージはエラー処理のための“End”ノードです。

![image-20250224164254256.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55902/886fe14b-f81d-414f-8adc-60171cc56fa6.png)
Androidアプリ初心者がハマった

## Androidをお勉強してたら謎が

ChatGPTに先生になってもらって、実機デバッグの仕方を勉強していた時の話。
ど素人なのでボタンタップのブレークポイントとか基本的なところを学習するためにサンプルコードを生成してくれとお願いしたところ、下記のxmlコードをくれた（MainActivity.ktもくれたけどｋ）。

``` activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center"
    android:padding="16dp">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:clickable="false"
        android:focusable="false"
        android:text="Hello World!" />

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="メッセージを表示" />

</LinearLayout>
```

ChatGPT先生のおかげで実機デバッグっぽくブレークポイントも動作して感動し、ボタンタップイベントも試せるコードだったのでボタンを押してみたが何も反応しない、タップ時にボタン色が反転するリアクションもない。
いろいろやっていると、
・もう一つボタンを追加すると動作する
・textViewとボタンをxmlで上下入れ替えると動作する
・layout_heightを固定値指定すると動作する
という感じだった。
理由をChatGPTさんにしつこく聞いたけどZが～とか、clickableが～とか、いろいろ教えてくれたがどれも上記の状態が説明できず。。。

初心者としては他にやることがいっぱいあるので一旦あきらめて、このメモを残すことにした。
きっといつか理解できるときがくるんだと信じて。
アニメ専用ティアメイカーを作ってみた

# はじめに

熊本高専3年生の岩元です。
アルバイト中に社員さんのリクエストで作成したアプリを共有します。
アニメの視聴履歴記録サービス「Annict」からユーザーの視聴履歴を取得し、ティア表を作成するWebアプリケーションを作りました。

[アプリケーションはこちら](https://animetier-54ccf.web.app/)

## 使用技術

- Firebase Authentication
- Firestore Database
- Firebase Hosting
- Firebase UI
- Vue Router
- Vue Draggable
- REST APIでのデータ取得

## アーキテクチャ図

![アーキテクチャ図](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3806026/0eed77e5-3d21-4482-b8cf-9ca882c0ed60.png)

# 環境構築

## 1. Node.jsをインストール

## 2. Vueプロジェクトの作成

```sh
npm create vue@latest
```

## 3. Firebaseの追加

1. Firebaseプロジェクトを作成し、アプリを登録
2. Firebase SDKのインストール

```sh
npm install firebase
```

3. Firebaseの設定ファイルを作成 (`src/firebase/init.js`)

```js
import { initializeApp } from "firebase/app";
import { getAnalytics } from "firebase/analytics";

const firebaseConfig = {
  // 設定情報をここに記述
};

const app = initializeApp(firebaseConfig);
const analytics = getAnalytics(app);

export { app, analytics };
```

[FirebaseをJavaScriptアプリに追加する](https://firebase.google.com/docs/web/setup?hl=ja)

## 4. Vue Routerのインストール

```sh
npm install vue-router
```

# 実装

## 1. ログイン機能の実装

[FirebaseUIでログイン機能を追加](https://firebase.google.com/docs/auth/web/firebaseui?hl=ja)

`auth.onAuthStateChanged` を使用し、ログイン状態に応じたルーティングを実装。

## 2. Firestoreのデータ取得

[Firestore Databaseのデータ取得方法](https://firebase.google.com/docs/firestore/query-data/get-data?hl=ja)

## 3. Annict APIリクエスト

[JavaScriptでHTTPリクエストを行う方法](https://developer.mozilla.org/ja/docs/Web/API/Fetch_API/Using_Fetch)

## 4. 画像の表示

## 5. ドラッグ＆ドロップ機能の実装

[Vue Draggableのサンプルコード](https://sortablejs.github.io/Vue.Draggable/#/simple)

# 感想

FirebaseUIの認証画面の実装に苦戦しました。
公式ドキュメントの内容が難しく最初は躊躇しましたが、最終的には公式を読み込むのが一番の近道だと感じました。
【AtCoder】使えそうな関数

【随時追加予定】

### 10進数をn進数に変換する関数

```C++
// 10進数をn進数(文字列)に変換する関数
string to_n_system(int sys, int x) {
  string res = "";
  do {
    res += to_string(x % sys);
    x /= sys;
  } while (x != 0);
  reverse(res.begin(), res.end());
  
  return res;
}
```
無料AIでPDFと画像をOCRするWebアプリ

## はじめに

「[無料AIでPDFと画像をOCRする](https://qiita.com/ka_yoshimu/items/5f871987986893c1571b)」をstreamlit cloud の Free 版で Webアプリにしました。

## Webアプリのアクセス先

https://ai-ocr-app-katsu-yoshimu.streamlit.app/

## 構築手順

1. Webアプリ ソースコード作成
    https://github.com/katsu-yoshimu/AI_OCR/blob/main/ai_ocr_app.py 参照

2. Streamlit cloud アカウント作成＆Webアプリ作成（Create app）
    [参考](#参考)を参照

3. Webアプリに Gemini APIキー設定
    [参考](#参考)を参照
    
    設定内容は以下のとおり
    ```
    # .streamlit/secrets.toml
    [gemini]
    api_key = "ここはご自分のAPIキー値を指定してください"
    ```

## 注意事項

- [Gemini API 追加利用規約](https://ai.google.dev/gemini-api/terms?hl=ja#data-use-unpaid)の『プライベート情報、機密情報、または個人情報を送信 しないでください。』が許容できるか？
- 無料枠なので1分間に15回。1日に1500回の実行上限がある
- PDF・画像ファイルのOCR結果の出力形式はHTMLのみ

## 参考

- https://qiita.com/shimmy-notat/items/4de7ed8a79d2f5b121da
    streamlit cloud 環境を構築する際に参考ささせていただきました。ありがとうございました。
- https://qiita.com/ushi05/items/3e51b218e3e45ef74ff4
    Gemini APIキーを設定する際に参考とさせていただきました。ありがとうございました。
Power Apps におけるデータ操作の関数について解説① 　～LookUp Filter Collect～

## はじめに
この記事ではPower Appsのアプリ内におけるデータ操作に関する関数について解説していきます。
データの読み込みや更新、削除においてデータの抽出方法はどの関数が最適か説明していきます。

## データ操作に関する関数のおおまかな分類
1\. **データの取得** 
　`LookUp` `First` `Last` `Filter` `Search`
2\. **データのフィルタリング・並び替え**
　`Filter` `Sort` `SortByColumns`
3\. **データの追加**
　`Collect` `Patch` `ForAll`
4\. **データの更新**
 　`Patch` `Update` `UpdateIf`
5\. **データの削除**
　`Remove` `RemoveIf` `Clear`
6\. **データの一時保存**
　`Collect` `ClearCollect`
7\. **フォームとの連携**
　`SubmitForm` `EditForm` `NewForm`

今回はこの中から比較的使用される関数について一部抜粋して解説していきたいと思います！


### LookUp関数
`LookUp` 関数は、データソースの中から**条件に一致する最初の1件のレコードを取得**する関数です。
もし条件に一致するレコードが複数ある場合でも、最初に見つかった1件のみを返します。

```ruby:基本的な書き方
LookUp(データソース, 条件 {,返したいフィールド})
```

以下に `社員名簿テーブル` があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3719434/5a0a6415-0eb0-44ca-82f7-08e4288fc985.png)


`部署 = 営業部` のレコードのみをギャラリーに表示させてみたいと思います。

```ruby:営業部でフィルター
LookUp(社員名簿テーブル,部署="営業部")
```

**検索結果**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3719434/51dc031a-977a-410d-bc82-13dff7cb3c94.png)


営業部は2名該当者が居ますが **`最初の1件のレコードが取得`** されるため
表示されるのは `田中 太郎` さんのレコードとなります。

:::note info
・{返したいフィールド}については省略可能です。条件のみだとレコードが格納されます。
・条件を複数指定したい場合は `And` や `Or` 関数で条件を指定してください。
:::

### Filter関数
`Filter` 関数は、データソース内のレコードの中から **指定した条件に一致するすべてのレコードを取得** するための関数です。

```ruby:基本的な書き方
Filter(データソース, 条件 , {,追加条件,...})
```

先ほどと同じように `社員名簿テーブル` を営業部でフィルターしてギャラリーに表示させてみたいと思います。

```ruby:営業部でフィルター
Filter(社員名簿テーブル,部署="営業部")
```

**検索結果**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3719434/5f271ed3-900d-4122-a039-67c5c477cc00.png)

先ほどの `LookUp` 関数では **条件に一致する最初の1件のレコードを取得** のみのため結果が1行しかありませんでしたが、`Filter` 関数は **指定した条件に一致するすべてのレコードを取得** するため今回は2行表示される結果となりました。

:::note info
追加条件を記入していくと必然的に `And` 条件としてみなされるため、記入は不要ですが `Or` 関数を使用する場合は必ず記入してください。
:::


### Collect関数
`Collect` 関数は、データをコレクション（仮のデータテーブル）に追加するための関数です。
Power Apps 内で一時的にデータを保存するため、データソースに直接影響を与えることがなく安全にデータを扱えます。

```ruby:基本的な書き方
Collect(コレクション名, データ)
```

例えば `MyCollection` というテーブルを作成してみます。

```ruby:MyCollectionというコレクションを作成
Collect(
    MyCollection,
    { Name: "田中 太郎",Department: "営業部"},
    { Name: "鈴木 花子",Department: "人事部"},
    { Name: "佐藤 健一",Department: "総務部"}
)
```

そしてギャラリーの `Items` に `MyCollection` を入れます。
作成されたコレクションを表示することができました。

**作成結果**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3719434/825f9248-7e39-422e-b89e-7437c32c9854.png)

**データソースからデータを取得してコレクションに保存**
データソースを取得してコレクションに保存することも可能です。

```ruby:データソースをMyCollectionに保存
Collect(
    MyCollection,
    社員名簿テーブル
)
```

**作成結果**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3719434/ebc0042b-a49e-4483-b5b1-3efec7967e6a.png)

`MyCollection` というコレクション名で表示させることができました。

## その①まとめ
本記事では `LookUp` `Filter` `Collect` 関数について紹介しました！
その他関数については随時作成中です！
ぜひご参考にしてみてください！

2025/2/27追記
その②についても作成を行いました！
ぜひご覧ください！

 **Power Apps におけるデータ操作の関数について解説② ～Patch Remove RemoveIf ClearCollect～**

https://qiita.com/Sanwa_Paint/items/fbb3d709e6cea8de47ad
ECCUBEプラグイン 4.2 → 4.3へ換装

# エラー

`An exception has been thrown during the rendering of a template ("Plugin\PluginName\Event::__construct(): Argument #1 ($twig) must be of type Twig_Environment, Twig\Environment given, called in /home/www/eccube-root/var/cache/dev/Container8nl8xnu/getEventService.php on line 29").
`

# 原因コード

```:root/app/Plugin/PluginName/Event.php
<?php

namespace Plugin\PluginName;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Eccube\Event\TemplateEvent;

/**
* ページをプラグイン用に差し替え
*/

class Event implements EventSubscriberInterface
{
    public function __construct(\Twig_Environment $twig)
    {
        $this->twig = $twig;
    }
    
    /**
     * @return array
     */
    public static function getSubscribedEvents()
    {
        return [
            'Cart/index.twig' => ['onTemplateCartIndex', 999999]
        ];
    }
    
    public function onTemplateCartIndex(TemplateEvent $event)
    {
        $source = $this->twig->getLoader()
            ->getSourceContext("@PluginName/default/Cart/index.twig")
            ->getCode();
                
        $event->setSource($source);
    }
}
```
14行目
`\Twig_Environment`
を
`\Twig\Environment`
で上書き

エラー解消
🚀【徹底比較】Cursor vs GitHub Copilot｜最強のAIコーディングアシスタントはどっち？

# はじめに  
AI時代のエディター戦争が本格化！  
特に「Cursor」と「Copilot」は、フリーランス・エンジニアにとって必須級。  
今回はどちらが優れているのか徹底比較する。  

## 1. コード補完力  
- **Cursor**: GPT-4 Turbo搭載。長文コードの補完に強い。  
- **Copilot**: OpenAI Codexベース。GitHubとの連携が強み。  

## 2. ワークフローの違い  
- **Cursor**: Chatで複数ファイルを編集可能。  
- **Copilot**: GitHubリポジトリのコード補完に最適。  

## 3. コスト比較  
- **Cursor**: 無料プランあり。Proプランは$20/月。  
- **Copilot**: 無料トライアル後$10/月。  

## 4. 結論  
✅ **柔軟なAI補完が必要ならCursor**  
✅ **GitHubと密接に連携したいならCopilot**  
どちらも試して、自分の開発スタイルに合うものを選ぼう！
Azure App ServiceとGitHubを連携してみた

## 1. はじめに

Azure App ServiceとGitHubを連携することに取り組んでみました。
以下の流れで進めた内容をまとめます。特に苦労した点や成功した点を振り返りながら、同様の課題に取り組む方々へ参考になればと思います。

## 2. 取り組んだこと

### 2.1 プロジェクトのセットアップ
ローカル環境でWebアプリケーションを作成するためのプロジェクトをセットアップしました。今回はapache-tomcat-9.0.99を導入しました。

### 2.2 コーディング（Java）
Javaを使用してアプリケーションのコーディングを行いました。特にビジネスロジックを実装する際に、設計を意識しながら進めました。

### 2.3 GitHubへのプッシュ
コーディング完了後、コマンドプロンプトを使用し、ソースコードをGitHubにプッシュしました。

### 2.4 Azure Portalでの動作確認
最後に、Azure PortalでApp Serviceを作成してGitHubと連携し、動作確認を行いました。これにより、アプリケーションが正しく動作するかをチェックしました。

## 3. 時間がかかったこと

### 3.1 WARファイル作成エラー
ローカルで作成したWebアプリケーションのWARファイル生成時にエラーが発生し、解消するまでにかなりの時間を要しました。

### 3.2 Gitの操作
コマンドプロンプト上でのGitの操作に不安があり、調査や動作確認に多くの時間を費やしました。特に、基本的なコマンドの使い方を理解するのに苦労しました。

### 3.3 Azureポータルのデプロイセンター
Azureポータルのデプロイセンターでの操作や設定が分からず、これにも多くの時間をかけました。デプロイ先設定や手順を理解するのに苦労しました。

### 3.4 AzureとGitHubの連携
AzureとGitHubの連携方法が不明で、こちらも調査や動作確認に時間がかかりました。正しい設定を見つけるのが大変でした。

## 4. 時間がかかったがうまくできたこと

### 4.1 WARファイルの作成
ローカルで作成したWebアプリケーションのWARファイルを無事に作成できました。この成果には非常に満足しています。

### 4.2 GitHubへのプッシュ
コマンドプロンプトを使用してGitHubへプッシュし、GitHub上でソースコードを確認できるようになりました。

### 4.3 Azureポータルの設定
Azureポータルのデプロイセンターでデプロイ先設定を完了しました。これにより、デプロイがスムーズに行えるようになりました。

### 4.4 AzureとGitHubの連携
AzureとGitHubの連携を成功させ、App Serviceの動作確認まで実施できました。これにより、今後の開発がよりスムーズになると感じています。

## 5. おわりに

Azure App ServiceとGitHubを連携する過程で、さまざまな課題に直面しましたが、クリアすることで得られた経験は大きな財産となりました。この経験を基に、次回はさらに効率よく進められるようにしたいと思います。今後も新たな技術に挑戦していくつもりです。
Oracle Database 19c Real Application Clusters インストール時のメモ

ORACLE 19c RAC構成の環境構築時に、インストーラによってノード間の ssh リンクは張れてるのに、インストーラが何故かエラーとなって先に進まない事象の対応方法メモ。
サポート契約なしに自力で RAC 環境を作る人はあまりいないかも知れませんが、ハマった方の参考となれば幸いです。

:::note warn
どこにもドキュメントがないので、自己流の解決方法です。
:::


■ インストール手順
https://www.oracle.com/jp/a/tech/docs/technical-resources/19c-racdb-installationguide.pdf
P40のノード間 ssh 接続に成功したのに、この先に進めない事象の対応内容です。

■ 対応方法
インストーラの scp コマンドの使い方に問題があるように思えます。
取り合えずエラーとならないように中身を書き換えてバイパスします。root で実行してください。

①scpコマンドを一旦退避します。
````
mv /usr/bin/scp /usr/bin/scp.orig
````

② バイパス版 scp コマンドを作ります。
````
vi /usr/bin/scp
````
③ 中身は下記の通りです。
````
/usr/bin/scp.orig -T $*
````

④ 実行権を付与します。
````
chmod 755 /usr/bin/scp
````

⑤インストールが完了したら、元に戻します。
````
mv /usr/bin/scp.orig /usr/bin/scp
````
[SwiftUI]サイドメニューをTab,Navigationの上に表示する

## fullScreenCoverを使用 
サイドメニューがタブ等の下に表示されるので、fullScreenCoverを使って前面に表示する


```swift:swift
extension View {
    
    func sideMenu(isPresented: Binding<Bool>) -> some View {
        self.modifier(SideMenuView(isPresented: isPresented))
    }
}
```

```swift:swift
struct SideMenuView: ViewModifier {
    
    @Binding var isPresented: Bool
    @State var showSideMenu: Bool = false
    
    private let width: CGFloat = 270
    
    func body(content: Content) -> some View {
        content
            .fullScreenCover(isPresented: self.$isPresented) {
                let bounds = UIScreen.main.bounds
                let screenWidth = bounds.width
                ZStack {
                    GeometryReader { _ in EmptyView() }
                        .background(Color.gray.opacity(0.3))
                        .opacity(self.showSideMenu ? 1.0 : 0.0)
                        .opacity(1.0)
                        .animation(.easeIn(duration: 0.25), value: showSideMenu)
                        .onTapGesture {
                            self.showSideMenu = false
                        }
                    HStack {
                        VStack {
                            // TODO: リスト部分
                            Spacer()
                        }
                        .frame(width: width)
                        .background(.white)
                        .offset(x: self.showSideMenu ? screenWidth - self.width : screenWidth)
                        .animation(.easeIn(duration: 0.25), value: self.showSideMenu)
                        Spacer()
                    }
                }
                .background(BackgroundTranslucentView())
            }
            .onChange(of: self.isPresented) { _, newValue in
                if newValue {
                    DispatchQueue.main.async {
                        self.showSideMenu = true
                    }
                }
            }
            .onChange(of: self.showSideMenu) { _, newValue in
                if !newValue {
                    DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
                        var transaction = Transaction()
                        transaction.disablesAnimations = true
                        withTransaction(transaction) {
                            self.isPresented = false
                        }
                    }
                }
            }
    }
}
```

```swift: swift
struct BackgroundTranslucentView: UIViewRepresentable {
    
    func makeUIView(context: Context) -> UIView {
        let view = UIView()
        DispatchQueue.main.async {
            view.superview?.superview?.backgroundColor = .black.withAlphaComponent(0.2)
        }
        return view
    }

    func updateUIView(_ uiView: UIView, context: Context) {}
}
```

## 注意
isPresentedをtrueにする際はwithTransactionで囲んでfullScreenCoverのアニメーションをしないようにする
MySql で件数報告（前回との差分付き）

MySql で、幾つかあるテーブルの件数を時々（毎日では無いという意味）集計して、前回の集計からどれくらい増えたかを報告するような SQL を試しました。
取り合えず 2 テーブル(atable/btable)で、ttable に集計を入れて select で表示させます。
```SQL
CREATE TABLE ttable (
    date DATE NOT NULL,
	asum INT NOT NULL,
	bsum INT NOT NULL,
	UNIQUE KEY `date`(`date`));
```
前回値が必要なので過去のテキトウな日付で 1 件
```SQL
INSERT INTO ttable(date, asum, bsum) VALUES ('2000-01-01',0,0);
```

で、集計する日に
```SQL
INSERT INTO ttable(date, asum, bsum)
	SELECT CURDATE(), SUM(a) AS asum, SUM(b) AS bsum
	FROM (
		SELECT COUNT(*) AS a, '0' AS b FROM atable
		UNION ALL
		SELECT '0' AS a, COUNT(*) AS b FROM btable) AS t
	ON DUPLICATE KEY UPDATE
		asum=VALUES(asum), bsum=VALUES(bsum);
```
とかすると
```
+------------+------+------+
| date       | asum | bsum |
+------------+------+------+
| 2000-01-01 |    0 |    0 |
| 2025-02-25 |    3 |    2 |
+------------+------+------+
```
のように行が増えて
```SQL
SELECT CONCAT('A合計 ',FORMAT(a2,0),'(+',FORMAT(a2-a1,0),')\n',
       'B合計 ',FORMAT(b2,0),'(+',FORMAT(b2-b1,0),')\n',
       '総合計 ',FORMAT(a2+b2,0),'(+',FORMAT(a2-a1+b2-b1,0),')') AS t
FROM
  (SELECT asum AS a2, bsum AS b2 FROM ttable ORDER BY date DESC LIMIT 1) AS c,
  (SELECT asum AS a1, bsum AS b1 FROM ttable ORDER BY date DESC LIMIT 1,1) AS p;
```
で
```
+---------------------------------------------+
| t                                           |
+---------------------------------------------+
| A合計 3(+3)
B合計 2(+2)
総合計 5(+5)        |
+---------------------------------------------+
```
となるのですね。
コピペで報告。

SELECT の FROM を LEFT OUTER JOIN に出来れば ttable の初期レコードは要らなくなるかもしれませんが、今の所出来るか分かりません。
~~UPSERT で使っている VALUES は無くなるそうなので別の書き方にしないといけないという記事は見ましたが、どうするんだったか忘れました。~~

***

UPSERT の VALUES() を行エイリアスにすると同時に、UNION ALL を列サブクエリにしてみたら、このほうがスッキリした感じです。
```SQL
INSERT INTO ttable(date, asum, bsum)
  SELECT * FROM (
	SELECT CURDATE() AS date,
           (SELECT COUNT(*) FROM atable) AS asum,
           (SELECT COUNT(*) FROM btable) AS bsum
  ) AS new
  ON DUPLICATE KEY UPDATE
	asum=new.asum, bsum=new.bsum;
```
ServiceNow Xanadu デルタ試験を受験！内容・対策・感想を解説

# 1.はじめに
ServiceNowの認定資格を維持するためには、定期的にデルタ試験を受ける必要があります。私自身、初めてこの試験を受けることになり、「どんな内容が出題されるのか？」「どのように準備すればよいのか？」と多くの疑問を抱きました。そこで、本記事ではデルタ試験の概要や出題範囲、効果的な学習方法についてまとめます。これから試験を受ける方がスムーズに準備できるよう、私の経験をもとに具体的な情報をお伝えします。

# 2.ServiceNowデルタ試験とは

### デルタ試験の目的
デルタ試験は、最新のServiceNowリリースで追加された新機能や、既存機能との相互作用を正しく理解していることを証明する試験です。（※デルタ試験仕様書より抜粋）
簡単に言えば、持っている知識に新バージョンの追加機能を組み込むための確認テストです。
ただし、不合格になると認定資格を維持できないため、資格保持者にとっては「維持のための必須手続き」とも言えます。

### 受験が必要な理由（認定資格の維持）
デルタ試験の目的は、「認定資格を維持するため」「新バージョンで追加された知識を定着させるため」の2つに集約されます。

### 受験対象者とスケジュール
すべての資格保有者（メインライン認定資格、Partner Sales & Pre-Sales Accreditation、マイクロ資格を含む）は、デルタ試験受講開始から90日以内に受験する必要があります。
詳細はServiceNowから届くデルタ試験受講案内メールに記載されています。

2025年 Xanaduリリースの試験期間
・2025年1月15日 ~2025年4月15日 (アメリカ時間)

# 3.試験の内容と出題範囲

### 試験で問われるポイント
デルタ試験は、最新のリリースノートとServiceNowの公式ドキュメントをもとに構成されています。
そのため、リリースノートを確認しながら解答できるのが特徴です。

私がXanaduリリースで受験した際は全10問で、リリースノートを見ればすべて回答可能な内容でした。

### 各リリースでの主な変更点の確認方法
変更点はリリースノートを見れば一目瞭然です。
特に、試験範囲の内容を重点的に確認しておくと良いでしょう。
[Xanaduリリースノート](https://www.servicenow.com/docs/ja-JP/bundle/xanadu-release-notes/page/release-notes/family-release-notes.html "Xanaduリリースノート")

# 受験の流れ

### 試験の申し込み方法
ServiceNowからデルタ試験の案内メールが届きます。
メール内のリンクをクリックするとNow Learningに遷移し、そこから受験できます。

### 試験の実施方法（オンライン/制限時間など）
・試験はオンライン、任意なタイミング受験可能（カメラ不要）
・制限時間は90分

### 合格基準と結果の確認方法
具体的な合格基準（何点以上で合格か）は公表されていません。
私は10問中8～9問正解で合格しました。
試験完了後、正解率と合否結果がすぐに表示されます。

# 受験時の注意点とポイント

### 試験直前に確認すべきこと
・リリースノートを確認することが最優先
・PDI（Personal Developer Instance）などの環境を触る必要はなし
・リリースノートを見ながら受験できるので暗記は不要

### 不合格時の対応（再受験の可否など）
・最大5回まで再受験可能
・ただし、再受験回数は試験ごとに異なる場合があるため、事前に確認推奨

# 最後に
この記事を読んでいる方は、初めてデルタ試験を受験する方や、不安を感じている方が多いと思います。
試験対策としてリリースノートの確認が最も重要であり、それだけで十分対応可能です。
試験前にもう一度確認したい方へ、参考リンクを紹介します。こちらの記事が皆さんの助けになることを願っています。

[ServiceNow認定資格進行ガイド](https://www.servicenow.com/jp/services/training-and-certification/journey/#/lessons/2wumKlpb3B-e_1Kn2Ro1c3x0lbINDvBk "認定資格進行ガイド")
[デルタ試験を完了する](https://learning.servicenow.com/lxp/en/credentials/%E3%83%87%E3%83%AB%E3%82%BF%E8%A9%A6%E9%A8%93%E3%82%92%E5%AE%8C%E4%BA%86%E3%81%99%E3%82%8B-completing-delta-exams-%E6%97%A5%E6%9C%AC%E8%AA%9E?id=kb_article_view&sysparm_article=KB0012209#:~:text=%E3%83%87%E3%83%AB%E3%82%BF%E8%A9%A6%E9%A8%93%3A,%E3%81%95%E3%82%8C%E3%82%8B%E3%82%8F%E3%81%91%E3%81%A7%E3%81%AF%E3%81%82%E3%82%8A%E3%81%BE%E3%81%9B%E3%82%93%E3%80%82 "デルタ試験を完了する")
SAPカレンダー（SCAL）

T-Code:SCAL
1.入力T-code
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3795764/7a5d5bca-77a7-453d-9d96-2d77d3d258f1.png)

2.选中对象国家，点击上面的「カレンダー」按钮
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3795764/9ac6202a-9e83-459b-a656-285227fd46c7.png)

3.进入下面画面后，选中希望查看的年份双击，或者点上方的照会
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3795764/9c534040-e5b3-4fdb-979e-44a0797259c0.png)

![img_v3_02jr_45cba479-2476-466d-b0ae-1cec33859bbg.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3795764/d24c834f-7801-48be-b473-13b3cece6c51.jpeg)
【Power Apps/SharePointリスト】キャンバスアプリ公開後、ギャラリーで画像が表示されない時の対応策（25年2月現在)

# 【起きていた問題】
PowerAppsでキャンバスアプリを作成し、
ギャラリーで画像を表示しようとしたが、画像が表示されませんでした。

色々、試してみてわかったんですが **"列の追加の仕方"が原因** でした。
あと、日本語の列名(内部列名)も原因になりうります。

## 【解決策】
SharePointサイトにて、
サイトコンテンツ＞該当するリスト名の横の…マークを選択。
「(リストの)設定」＞ **「列の作成」** を選択する、または 
「(リストの)設定」＞ **「サイト内の既存の列から追加」** を選択して
「サイト列の選択元：基本の列」を選び「URL」を追加する。
⇒このやり方で追加する。
必要なデータを列に入力したのち、Apps側のテーブルで該当するリストを
「最新の状態に更新」し、アプリを公開。

 **⇒この方法だと、ギャラリー、およびデータテーブルでも表示されました。** 

ちなみに、上記のやり方にしても、列名を日本語で入力すると、
内部列名が　_x71c9__x123b みたに、"_(アンダーバー)"で始まる列名になってると、
ギャラリーでうまく取得できなくなっちゃいます。
なので、極力、最初に登録するときは列名を英語で登録して、
その後、日本語の列名に変更する。という手順をとった方がよいです。


## 【やったらダメなこと】
サイトコンテンツ＞リスト名クリック後に表示される画面「URLの末尾が～/AllItems.aspx」のページ。
ここで「列の追加」＞「種類：ハイパーリンク」を選択して作成した列は
なぜか、公開したアプリのギャラリー、およびデータテーブルでは表示されません。
編集モードでは問題なく表示されてるんですが謎です。
※内部列(OData_xxxxxx形式のやつ)で指定しても表示されません。

以上、
原因は謎ですが、一旦、この問題で悩んでいる人がオープンチャット等、見受けられたのでQiita記事として残しておきます。

ちなみに、上記の答えに辿り着くまで、下記のような形で原因を探っていました。
それもメモとして残します。

## 【試したこと①】データの有り・無しの確認。
ギャラリー、およびデータテーブルの該当Itemのところに
If(IsBlank(ThisItem.列名),"データなし",ThisItem.列名)
と記述して様子を見ました。
編集モードでは、問題なくテーブルのデータが表示されます。
アプリ公開してみると、該当する箇所は"データなし"と表示されてしまいます。

##【試したこと②】ライブ監視 機能を使った。
Power AppsのStudioのアプリ一覧からアプリ名横の「…」をクリックして
「詳細」＞「ライブ監視」を実行。
「公開したアプリの再生」で新規ウィンドウで立ち上がったアプリを操作してみる。
ライブ監視ツールの右上にある「オプション」は詳細を選択、密度はコンパクト。

該当する、テーブルからデータを取得しようとしてる箇所の結果

カテゴリ：Verbose 
操作：parsing
結果：警告
結果情報：
data": {
    "info": "サーバーからの応答に予期しない列があり、それらは無視されています。",
    "droppedColumns": [
      "ItemInternalId"
    ]


と表示されていました。

以上、同じような症状が起きている方、試してみてください。
解決することを祈ります！
【情報セキュリティマネジメント試験対策】認証について

:::note info
「パスワード認証」とは
個人の知識により利用者を認証する。
パスワードの文字の種類と長さを十分に保ち、推測されにくいものにする。
:::

:::note info
「バイオメトリクス（生体）認証」とは
身体的特徴や行動的特徴から利用者を認証する。
・FRR（本人拒否率）：本人を他人と誤認識・拒否する確率
・FAR（本人受入率）：他人を本人と誤認識・拒否する確率
:::

:::note info
「2要素認証」とは
個人の知識（パスワード）と物理的な物（ICカードや生体認証）を組み合わせて認証を行うこと。
:::

:::note info
「リスクベース認証」とは
アクセス元など利用者のいつもと異なるアクセスに対して追加の認証を行う。
:::

:::note info
「CAPCHA」とは
ロボットではなく人からのアクセスであることを確認するために、歪んだ文字などの入力を求め、その結果を分析すること。
:::

:::note info
「パスワードなどを推測する攻撃」
＜辞書攻撃＞
辞書に掲載されているような文字をパスワードとして試す。

＜総当たり（ブルートフォース）攻撃＞
IDを固定してパスワードを試す。

＜逆総当たり（リバースブルートフォース）攻撃＞
パスワードを固定してIDを試す。

＜パスワードリスト攻撃＞
あるサイトから流出したIDtoパスワードを他のサイトで試す。
:::

:::note alert
「バイオメトリクス認証には身体的特徴を抽出して認証する方式と、
行動的特徴を抽出して認証する方式がある。行動的特徴を用いてるものはどんなものか？」
:::

:::note warn
答え：署名するときの速度や筆圧から特徴を抽出して認証する。

誤り：「隆線によって形作られる紋様からマニューシャと呼ばれる特徴点を抽出して認証する。」
これは指紋認証のようなもので身体的特徴を抽出して認証してるので誤り。
:::

:::note alert
「虹彩認証に関する記述のうち、適切なものは？」
:::

:::note warn
答え：他人受入率を顔認証と比べて低くすることができる。

虹彩認証は顔認証よりも高い精度で本人を識別できる場合があります。虹彩のパターンは個人ごとに異なり、変化が少ないため、顔認証に比べて他人受入率（誤認識率）を低く抑えることが可能です。虹彩認証は非常に独自性が高く、顔認証に比べて精度が向上することがあります。
　
と問題集には載っていましたが、

「経年変化による認証精度の低下を防止するために、利用者の虹彩情報を定期的に登録し直さなければならない。」

調べたところこれ↑も正しいみたいです。

誤り：「赤外線カメラを用いると、照度を高くするほど目に負担をかけることなく認証精度を向上させることができる。」

照度を高くしすぎると目に負担をかける可能性があるため、「目に負担をかけることなく」という部分が誤りです。

 
「本人が装着に接触した後に残された遺留物を採取し、それを加工することによって認証データを偽造し、本人に成り済ますことができる。」

虹彩認証は目の内部の虹彩パターンを利用して識別を行うため、目の表面に残った遺留物を使って偽造することはほぼ不可能です。虹彩のパターンは目の奥にあるため、目の表面の遺留物を採取しても虹彩データを偽造することは現実的に困難です。この主張は誤りです。 
:::
68. Text Justification 解答例・ポイント

# 問題内容
複数の英単語で構成されるリストと最大幅の数値を入力したとき、スペースを挟んだ並びにしつつ最大幅に収めた文字列のリストを出力するようにコードを完成させよというもの。スペースについては、左側のものほど連続しやすくする。

# 解答例
```python:sample
class Solution:
    def fullJustify(self, words: List[str], maxWidth: int) -> List[str]:
        res, cur, num_of_letters = [], [], 0
        for w in words:
            if num_of_letters + len(w) + len(cur) > maxWidth:
                for i in range(maxWidth - num_of_letters):
                    cur[i%(len(cur)-1 or 1)] += ' '
                res.append(''.join(cur))
                cur, num_of_letters = [], 0
            cur += [w]
            num_of_letters += len(w)
        return res + [' '.join(cur).ljust(maxWidth)]

```

# ポイント
上記のコードは、
- 最大幅の1行につき、いくつ単語を入れられるか
- その行内でスペースをどのように配置するか
について考えることを軸にしています。

一つ目のポイントは下の行にあたります。
```python
if num_of_letters + len(w) + len(cur) > maxWidth:
```
num_of_lettersは同一行に含められる単語の総文字数、len(w)は新しく加えることになる単語の文字数、len(cur)はそれらの間に入るスペースの数。これらの和が最大幅を超えるまで繰り返します。

２つ目のポイントにあたるのは次の部分です。
```python
for i in range(maxWidth - num_of_letters):
   cur[i%(len(cur)-1 or 1)] += ' '
```
ここでは、その行に挿入されるスペースの数に応じてループするようになっています。
そして、上記のような剰余を利用することで左側ほどスペースが挿入されやすくなります。
```
or 1
```
途中にある、この記述はlen(cur)-1が０のときに備えてのものです。


補足として、
```python
return res + [' '.join(cur).ljust(maxWidth)]
```
最後の+以降の記述は入力リストに単語が１つだけ入っている場合に備えたものです。
ljust関数によって、最大幅内で左詰めとなって出力されます。
IBM i Services Directory : QSYS2.NETSTAT_Job_Info ビュー

5250でのNETSTATコマンド オプション 3. IPV4接続状況の処理　（または6. IPV6接続状況）と同様な結果を返します。

## 概要
■ビュー名：QSYS2.NETSTAT_JOB_INFO
■カテゴリ：通信サービス
■サポート：IBM i 7.2 SF99702 Level 9以降, Level 11, Level 23 で拡張
■参照URL（IBM i 7.5）：https://www.ibm.com/docs/ja/i/7.5?topic=services-netstat-job-info-view

## 実行例①
IPV4で接続しているジョブの一覧を返します。
```
SELECT * FROM QSYS2.NETSTAT_JOB_INFO
  WHERE CONNECTION_TYPE = 'IPV4' ;
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011394/886a1a52-c7bc-4555-8ea5-5c3c552b0d87.png)

上記の辺はIBM i で起動しているローカルポートの状況ですね、
スクロールすると、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011394/6eaa01b6-4d37-4db7-87d6-6454cbb3a98c.png)


Job Nameを見るとIBM i での関連ジョブを確認する事が出来ます。

### 参考：5250 NETSTATコマンド オプション 3.の実行例

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011394/c4e5d90c-2ca4-4831-b67d-5fe54b336ff8.png)

※上記の画面でローカルポートがポート番号でなくas-file-s などと記載されているものはIBM i でサーバージョブ（デーモン）が使用しているポートです。ポート番号を表示させたい場合は PF14キー　ポート番号の表示　を押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011394/596dba21-ab2f-4409-83bb-8f1b404e7997.png)

任意のポート番号のOPT欄に 5.詳細の表示　を入力してエンターキーを押すと、クライアントのIP,ポートほかの情報を表示できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011394/c48859fd-d07d-4173-9e57-34c218ea0bbe.png)
※IPはマスクしています。
GROWIでコードの折り畳み表示をサポートするプラグインを作りました

[オープンソースのWikiであるGROWI](https://growi.org/ja/)にはプラグイン機能が用意されています。自社のデータを表示したり、表示をカスタマイズするのに利用できます。

今回は、GROWIプラグインとしてコードの折り畳みを行えるプラグインを作りました。設定なしで、すぐに利用できます。

![名称未設定.mov.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/801206ec-377a-49fe-94a0-50326f34d30c.gif)

## プラグインの動作

Markdownのコードブロック（インライン除く）を `<details />` でラップするだけのシンプルな動作です。デフォルトはオープンです。

![FireShot Capture 563 - _ - GROWI - localhost.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/578cbf83-fb5d-46af-9d6a-39909434283c.jpeg)

クリックすれば、折りたたまれます。

![FireShot Capture 564 - _ - GROWI - localhost.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/3c923508-7c3f-4b48-993b-311623100604.jpeg)


## プラグインを追加する

利用する際には、GROWIの管理画面の `プラグイン` にて追加してください。URLは `https://github.com/goofmint/growi-plugin-folding` です。

![Admin](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/f5b3e2d3-ccf3-d536-d59e-7301ea1b2f7e.jpeg)

## コードについて

コードは[goofmint/growi\-plugin\-folding](https://github.com/goofmint/growi-plugin-folding)にて公開しています。ライセンスはMIT Licenseになります。

見ての通り、 `<details />` で囲んでいるだけです。 `ignore` というフラグを追加しているのは、 `code` ブロックが2回呼ばれる（`<details />` で囲んでいるので、ネストが1つ深くなる）ので、すでに処理済みであることを判別するためです。

```tsx
export const foldingCode = (Tag: React.FunctionComponent<any>): React.FunctionComponent<any> => {
  return ({ children, ...props }) => {
    try {
      if (!props.inline && !props.ignore) {
        props.ignore = true;
        return (<details open={true}>
          <Tag {...props}>{children}</Tag>
        </details>);
      }
    }
    catch (err) {
      // console.error(err);
    }
    // Return the original component if an error occurs
    return (
      <Tag {...props}>{children}</Tag>
    );
  };
};
```

## growi-foldingの動作

特別な記載なく動作します。本プラグインを入れると、すべてのコードブロックが折り畳み対象になります。

## GROWIコミュニティについて

プラグインの使い方や要望などがあれば、ぜひGROWIコミュニティにお寄せください。実現できそうなものがあれば、なるべく対応します。他にもヘルプチャンネルなどもありますので、ぜひ参加してください！

[GROWI Slackへの参加はこちらから](https://communityinviter.com/apps/wsgrowi/invite)

## まとめ

GROWIプラグインを使うと、表示を自由に拡張できます。足りない機能があれば、どんどん追加できます。ぜひ、自分のWikiをカスタマイズしましょう。

[OSS開発wikiツールのGROWI | 快適な情報共有を、全ての人へ](https://growi.org/ja/)
AWS Organizations/IAM Identity Centerでできること

AWS OrganizationsとIAM Identity Centerとでできる作業についｔ混乱することがよくあるので、簡単に整理します。

## AWS Organizations
・AWSアカウントの作成/招待
・OU（組織単位）の作成
・SCP（サービスコントロールポリシー）の作成
・SCPのOU/アカウントへのアタッチ
⇒<INS>アカウントとOUとの関係性を定義</INS>

## IAM Identity Center
・ユーザーの作成
・グループの作成
・グループへのユーザー追加
・許可セットの作成
・ユーザー/グループを許可セットを適用してアカウントへ割り当てる
⇒<INS>ユーザーとアカウントとの関係性を定義</INS>