OmniAICreator/Qiita-1.07M huggingface dataset:
Kotlin Multiplatform(Android/iOS)でビルド環境ごとに対応した値を利用したい

# やりたいこと
Debug/Releaseのビルドで環境に対応したAPIのURL等を用意したい。

# やり方
1. Android・iOS、それぞれの環境でビルド時の設定値を用意する
1. expect/actualで参照する

# サンプル：環境に対応したAPIのURLを用意する手順
## 1. Androidでビルド時の設定値を用意
gradleでdebug/release環境それぞれのAPIのベースとなるURLを用意します。
こうすることで`Sync now`すると`your-app/BuildConfig.java`が作成され、`BuildConfig.API_BASE_URL`とすると設定値を読み出すことができます。
```kotlin:build.gradle.kts
buildTypes {
    getByName("debug") {
        buildConfigField("String", "API_BASE_URL", "\"http://10.0.2.2:4001\"")
    }
    getByName("release") {
        isMinifyEnabled = false
        buildConfigField("String", "API_BASE_URL", "\"https://example.com\"")
    }
}
```

## 2. iOSでビルド時の設定値を用意
デフォルトでInfo.plistファイルがあるのですがこれをDebug用とRelease用に分けます。
```xml:iosApp/iosApp/Info-Debug.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    ....
    <key>API_BASE_URL</key>
    <string>http://localhost:4001</string>
</dict>
</plist>
```
```xml:iosApp/iosApp/Info-Release.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    ....
    <key>API_BASE_URL</key>
    <string>https://example.com</string>
</dict>
</plist>
```
xcodeでプロジェクトを開き、Debug/Releaseビルド時に上記で指定したファイルを参照するように設定
1. 左側の階層からiosAppをクリック
1. Build Settings > TARGETS > iosApp > Packaging > Info.plist File
1. 以下に変更
    - Debug：iosApp/Info-Debug.plist
    - Release：iosApp/Info-Release.plist
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1045272/9b8581fe-ff64-49ac-9f25-26990259908c.png)

## 3. expect/actualを実装
```kotlin:kotlin/your-app/common/Config.kt
expect object Config {
    val apiBaseUrl: String
}
```
```kotlin:kotlin/your-app/common/Config.android.kt
import jp.d_publishing.directbooks.BuildConfig

actual object Config {
    actual val apiBaseUrl: String
        get() = BuildConfig.API_BASE_URL
}
```
```kotlin:kotlin/your-app/common/Config.ios.kt
import platform.Foundation.NSBundle

actual object Config {
    actual val apiBaseUrl: String
        get() =
            NSBundle.mainBundle
                .infoDictionary
                ?.get("API_BASE_URL") as? String
                ?: error("API_BASE_URL not found in Info.plist")
}
```

# 終わりに
スマホアプリ開発初心者の私にとって「環境ファイル的なものを一つ用意するだけでどのプラットフォームでもいい感じに動くものでしょ」と思っていましたがそんなことはなかったです。もし知っている方がいらっしゃればコメントをお願いします。同じような感覚のスマホアプリ開発初心者にとってこの記事の内容が参考になれば幸いです。
dependenciesの定義場所で変わるビルドの世界（AGP vs KMP）

Kotlin Multiplatform（KMP）プロジェクトにおいて、Gradleの`dependencies`定義に混乱したことはありませんか？

特に、「トップレベルの`dependencies`と`sourceSets`内の`dependencies`って何が違うの？」「依存関係どっちの`dependencies`に追加したらいいの？」と感じた方も多いはずです。

本記事では、Android Gradle Plugin（AGP）とKMPプラグインがそれぞれ管理する`dependencies`の違いをわかりやすく整理します。

## Gradleプラグインの役割整理

### 🔧 Android Gradle Plugin（AGP）

[公式ドキュメント](https://developer.android.com/build/extend-agp?hl=ja) によれば、AGPは **Android特有のビルド処理** を行うGradle拡張プラグインです。

```kotlin
plugins {
    alias(libs.plugins.androidApplication)
    // → "com.android.application"
}
````

これにより、Androidアプリ向けのビルド設定が自動化されます。


### 🌐 Kotlin Multiplatform Plugin（KMP）

[KMP公式ガイド](https://plugins.gradle.org/plugin/org.jetbrains.kotlin.multiplatform) によれば、KMPプラグインは **共通のKotlinコードを複数プラットフォームにコンパイル** する仕組みを提供します。

```kotlin
plugins {
    alias(libs.plugins.kotlinMultiplatform)
    // → "org.jetbrains.kotlin.multiplatform"
}
```

## Q. AGPとKMP、どちらかだけでOK？

**A. NO！**

KMPプロジェクトにおいても、**AndroidビルドにはAGPが必須**です。

AGPとKMPは以下のような住み分けで動作します：

| プラグイン | 主な責任                   |
| ----- | ---------------------- |
| AGP   | Android向けビルドタスクの処理     |
| KMP   | 共通コード・マルチプラットフォーム出力の管理 |

## `dependencies` の違い：定義場所で作用範囲が異なる！

### 1. トップレベルの `dependencies`

```kotlin
dependencies {
    implementation("androidx.core:core-ktx:1.10.1")
}
```

* **管理者：AGP**
* **対象範囲：Androidモジュール全体**
* Androidアプリ単体でビルドしているときと同様の扱い

### 2. `sourceSets` 内の `dependencies`

```kotlin
kotlin {
    sourceSets {
        val commonMain by getting {
            dependencies {
                implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3")
            }
        }
    }
}
```

* **管理者：KMPプラグイン**
* **対象範囲：プラットフォーム別のコードベース**

  * 例：`commonMain`, `androidMain`, `iosMain` など

## Q. なぜ `commonMain` の依存関係が `androidMain` や `iosMain` からも参照できるの？

**A. `commonMain` は各プラットフォームのベースになるからです。**

KMPでは、`commonMain`が基底ソースセットとして機能し、各プラットフォームのソースセット（`androidMain`、`iosMain`など）がこれを「継承」する構造になっています。

これはGradleのマルチプラットフォームプラグインが持つ **暗黙的な継承機構** に基づいています。

参考：[The basics of Kotlin Multiplatform project structure - SourceSets](https://www.jetbrains.com/help/kotlin-multiplatform-dev/multiplatform-discover-project.html#source-sets)

## まとめ

* AGPとKMPは別々の目的で動作している
* `dependencies`の定義場所で作用範囲が変わる
* `commonMain`の依存関係は、プラットフォーム側でも使えるように設計されている

## おわりに

KMP導入初期にぶつかりがちなこの依存関係の違い、理解が進めば柔軟なアーキテクチャ設計が可能になります。

似たような悩みを持っている方は多いと思うので、本記事がその一助となれば幸いです 🙌
【Diff】文章を効率的にマージするためのサイトを公開してみる

ChatGPT でプログラミングしていると
一部のコードを勝手に削除する現象が発生するため
必要な修正点のみをマージするための
サイトを作成しました。

マージ作業全般が効率化されます。

無料かつ登録なしで使用できますので
よろしければご利用下さい。

[オンラインサイトはこちら](https://uni928.github.io/DiffTextEditor/)
[BOOTH でダウンロードしたい方はこちら](https://giftedstyle.booth.pm/items/6959325)

![説明画像2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3752886/3737c4fc-a089-4355-8fc5-8f0bd8c6ccc4.png)

![タイトルなし.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3752886/97e11fc1-3550-4780-9479-09a2708338fc.png)

***

サイトの説明

📘 Diff 文差分エディタ（無料ツール）

このHTMLアプリは、2つの文章を文単位で比較し、差分を視覚的に表示・適用できる「テキスト差分エディタ」です。
Googleの「diff-match-patch」ライブラリを利用しており、追加・削除された文をハイライト表示しながら、
差分の一方をもう一方にワンクリックで反映できます。

🚀 特徴
- 文単位の比較により、構造のズレを軽減
- Apply ボタンで片側の文章に反映可能
- Ctrl + Z で Undo、Ctrl + Y で Redo に対応
- 文章の校正、マージ、AI出力結果の比較などに便利

🧠 Undo / Redo に対応
Apply操作ごとに状態を自動で保存しており、編集操作を簡単に巻き戻すことができます。

📜 使用ライブラリ
- diff-match-patch（Apache License 2.0）  
  https://github.com/google/diff-match-patch

📎 利用例
- ドキュメントの校正・レビュー
- 翻訳文や生成AI文との比較・編集
- 複数バージョンの文章マージ
- チームでの編集確認作業

⚠️ 免責事項
本ツールはあくまで補助的な用途を目的としたものであり、内容の正確性や変換結果について保証するものではありません。
ご利用にあたっては自己責任でご判断ください。

***

追記

察している方は察していると思いますが
後半の文章は ChatGPT で添削しています。

生成 AI の添削が嫌いな方は
申し訳ありません。
同期処理と非同期処理どちらがあっているかの検討基準

**結局のところ、扱っているシステムの特徴や状況を踏まえて、何を満たす必要があるのか、非同期処理でないと実現できないのか、メリットデメリットを整理して判断したほうが良いのでは。検討する際の観点候補が下記。**

# 同期処理と非同期処理の判断基準
## 1. 処理の即時性
- **同期が適する場合**: ユーザーが即時結果を求める  
  - 例: 決済処理、ログイン認証
- **非同期が適する場合**: 処理に時間がかかるため、待たせない方が良い  
  - 例: ファイル生成、動画エンコード

## 2. データの整合性
- **同期が適する場合**: 処理順序が厳密で、確実に適用される必要がある  
  - 例: 在庫管理、銀行取引
- **非同期が適する場合**: データ更新の順番が厳密でなくても問題ない  
  - 例: 分析データ集計、バッチ処理

## 3. システム負荷とスケーラビリティ
- **同期が適する場合**: 処理負荷が少なく、単純なリクエストで済む  
  - 例: API経由の小規模なデータ取得
- **非同期が適する場合**: 大量のリクエストが発生し、並列処理が有効  
  - 例: チャットアプリ、ゲームサーバー

## 4. 外部サービスとの連携
- **同期が適する場合**: 外部APIの結果を即時取得し、確定させる必要がある  
  - 例: 決済API、認証API
- **非同期が適する場合**: 外部サービスの応答が遅延し、待機時間を減らしたい  
  - 例: 天気予報データ取得、バックグラウンド処理

## 5. ユーザー体験
- **同期が適する場合**: 操作結果を即時表示しないとユーザーが混乱する  
  - 例: フォーム送信の確認、購入完了画面
- **非同期が適する場合**: ユーザーが待機せず、バックグラウンドで処理できる  
  - 例: ダウンロード、通知送信

# まとめ
同期・非同期の選択は **「即時性」「整合性」「負荷」「外部サービス」「ユーザー体験」** の観点で判断する。  
それぞれの用途に応じて適切な設計を考えることが重要。
【git】dependabot.ymlによるtailwindのバージョン変更の対処


## はじめに

こんにちは。アメリカ在住で、独学でエンジニアを目指している Taira です。
現在 rails アプリ開発中ですが、その際に git 関連のトラブルがあったので反省や復習の意を込めて記事にしようと思いました

## 発生した問題

`git log` を確認したところ、以下のようなログが表示されました：

```
fbfaa41 (HEAD -> main, origin/main) Change to weekly .github/workflows/dependabot.yml
0185da7 Merge pull request #1 from Taira0222/dependabot/bundler/tailwindcss-rails-4.2.3
d091abc Merge pull request #2 from Taira0222/header-erb
1037a3e (origin/header-erb) Finish header-erb with js
22df726 Bump tailwindcss-rails from 3.3.1 to 4.2.3
a46c2fe Initialize commit
```

この中で `22df726` のコミットが `tailwindcss-rails` のバージョンを 3.3.1 から 4.2.3 に上げており、**Dependabot による自動 PR によって意図せずバージョンが更新されてしまったこと**が問題の発端でした。

## 私がとった対応

TailwindCSS の挙動に異変を感じ、すぐに変更を戻そうと以下のコマンドを実行しました：

```bash
git revert 1037a3e --no-edit
```

これにより、1037a3e の変更を打ち消す新たなコミットが作られ、結果的に**正常に動作していたコードが消えてしまいました**。

その後、以下のコマンドで強制的に元の状態へ戻しました：

```bash
git reset --hard 1037a3e
git push -f origin main
```

これにより、GitHub 上のコミット履歴を 1037a3e の時点に戻すことができました。
しかし、上記の作業だとチーム開発では履歴が残らなかったり、コンフリクトを招くリスクが高いのでやるべきではなかったと反省しています。

## 本来とるべきだった対応

意図しないバージョンアップの原因である `22df726` のみを revert すればよかったのです：

```bash
git revert 22df726
```

### この操作の意図

- `22df726` = `Bump tailwindcss-rails from 3.3.1 to 4.2.3`
- 自動 PR で作成されたこのコミットだけを取り消す
- `git revert` は変更を「打ち消す」新しいコミットを作成するため、安全に操作可能

## `git revert` の解説

### `git revert` とは？

- 特定のコミットの変更を打ち消す新たなコミットを作成するコマンド
- コミット履歴自体は残るが、結果的にその変更は無効化される

### `git reset` との違い

- `reset`：履歴を書き換えて後続のコミットを消す
- `revert`：履歴を保ったまま変更だけを打ち消す
- **チーム開発では履歴の保全のため `revert` を優先するのが基本**

## まとめ

今回の問題は Rails8 に搭載されている Dependabot が `tailwindcss-rails` のバージョンを自動的に上げてしまったことにより発生しました。

**意図しない変更を反映させたくない場合は、当該の bump コミットのみを `git revert` するのが最適な対処法であると思います。**

`git reset` は履歴を書き換えるため、**公開ブランチでは使わないのがベストプラクティス**です
初心者向け解説：いま話題の「能動的サイバー防御」とは？

## はじめに

「能動的サイバー防御」という言葉を、最近ニュースなどで見かけた方も多いのではないでしょうか。　
**2025年5月、能動的サイバー防御を導入するための関連法が成立しました。**
可決されたのは、「**サイバー対処能力強化法**」（重要電子計算機に対する不正な行為による被害の防止に関する法律）及び、「**同整備法**」（重要電子計算機に対する不正な行為による被害の防止に関する法律の施行に伴う関係法律の整備等に関する法律）です。
この新たな防御戦略は、サイバー攻撃が高度化・巧妙化する中で、**“受け身から攻め”への転換**を意味します。




私はこのニュースを見て「そもそも“能動的”って何？」「政府はどこまで踏み込むの？」「海外と比べてどう違うの？」といった疑問が浮かび、調べてみた内容をまとめました。

本記事では、同じような疑問を持った方に向けて、初心者にもわかりやすく解説します。



## 能動的サイバー防御とは？

### サイバー攻撃の深刻化

* 警察庁によると、2024年の1年間で**日本に届くサイバー攻撃の99%以上は海外発**。
* 医療・港湾・宇宙機関などでも被害が発生。
* 脅威アクター(サイバー攻撃を実行する組織等)によるインフラ侵害など、国家規模の攻撃も懸念。
> 🔍 約13秒に1回、日本ではサイバー攻撃が発生していると言われています。

### なぜ今、法整備が必要か

* 通信情報の活用には明確な法的根拠がなかった
* 攻撃元サーバーに対応する権限が限定的だった
* 官民の情報共有が不十分だった


### 従来の「受動的防御」との違い

**受動的防御とは**

サイバーセキュリティにおける受動的防御（Passive Defense）とは、ファイアウォールやアンチウイルスソフト、侵入検知システム（IDS）などを使って、サイバー攻撃が発生した際にその影響を最小限に抑えることを目的とした防御手法です。

受動的防御の特徴：

* 攻撃に対するリアクティブ（反応的）な対応
* 外部からの侵入を防ぐ壁（バリア）を構築
* 被害の拡大を防ぐが、攻撃の出所や再発防止には限界がある


上記のとおり、従来の防御（ファイアウォールなど）では、攻撃"後"の対応が中心でした。

**能動的サイバー防御**は、
* 攻撃の兆候を**事前に検知**
* 攻撃元に**アクセスして無害化**
* **政府と民間が連携**して対応

といった**積極的な対応**を行うことが特徴です。

| 特徴 | 受動的防御 | 能動的防御 |
|------|------------|------------|
| タイミング | 攻撃後に対応 | 攻撃前・進行中に対応 |
| アプローチ | 監視・遮断などの防御中心 | 攻撃元への対応（積極介入） |
| 主体 | 各組織が個別に対応 | 政府が主体（官民連携） |



## 新法による主な仕組み

### 1. 通信情報の利用（強化法）

* 対象：IPアドレス、接続時刻などの**メタデータ**（通信内容は含まない）
* 主体：内閣官房（新組織）が取得・分析
* 方法：
  * 同意による取得（インフラ事業者などと協定）
  * 同意なしでも独立機関の承認を得て取得可能
  * 自動的に**関係ある情報のみを抽出し、他は破棄**
* チェック機関：**サイバー通信情報監理委員会**が事前承認・後監査を担当

### 2. アクセス・無害化措置（整備法）

* 攻撃に使われたサーバーに対して、**マルウェアの無効化、通信遮断**などを実施
* 主体：
  * **警察庁の指定職員**（サイバー危害防止措置執行官）
  * **防衛省・自衛隊**（国家的・高度な攻撃時）
* 実施には、**独立機関の承認**と**関係大臣の指揮**が必須

### 3. 官民連携（強化法）

* 政府と重要インフラ事業者・ITベンダーなどが参加する**新しい協議会を設置**
* サイバー攻撃や脆弱性の情報を共有
* インシデント発生時の報告義務や届出制度の創設


## 法律上の安全措置

* 通信の秘密（憲法21条）やプライバシー保護を尊重
* 最小限の権限行使、使用目的を限定
* 取得データの選別・破棄を厳密に実施
* 不適切な利用に対しては**罰則**あり（例：漏えいは懲役や罰金）



## 海外との違い

| 国     | 通信情報の活用               | アクセス・<br>無害化の制度       | 監視機関の有無         |
| ----- | --------------------- | ----------------- | --------------- |
| 日本    | メタデータに限定・独立監視委員会の承認必須 | 令状・承認制／限定的に実施可能   | サイバー通信情報監理委員会 |
| 米国    | FISA法に基づき広範囲に<br>取得可能     | ボットネットへの<br>無害化措置事例あり | FISCなど        |
| 英国・豪州 | 傍受法（IPA, TOLA等）により収集・利用が可能      | 国家安全目的で<br>実施可能       | IPCO（英）<br>IGIS（豪）など      |


## まとめ

今回の法整備により、日本でも**攻撃の予兆を早期に察知し、実際の攻撃を未然に防ぐ枠組み**が整いました。
これにより、国家レベルのサイバー攻撃に対しても、政府が迅速に動ける体制が構築され、**国民の安心・安全を守るための一歩**が踏み出されたと言えるのではないでしょうか。
**透明性・信頼性・説明責任**が伴ってはじめて、それは真に「安心」につながります。
ですので、これからも関連ニュースを確認してより理解を深めていきたいと思います。

> 🔐 **セキュリティは技術だけでなく、社会との合意形成でもある。**





## 参考リンク

- [内閣官房：サイバー安全保障に関する取組](https://www.cas.go.jp/jp/seisaku/cyber_anzen_hosyo_torikumi/index.html)
- [令和６年におけるサイバー空間をめぐる脅威の情勢等について（警視庁）](https://www.npa.go.jp/publications/statistics/cybersecurity/data/R6/R06_cyber_jousei.pdf)
マイクロサービスなWebサーバを実現するHelidonを実務で使っていく！その２

# マイクロサービスなWebサーバを実現するHelidonを実務で使っていく！
### その２ Helidonプロパティを動的にオーバーライドする！
こんにちは、エンジニアのtakemuraです。前回鼻息荒くHelidonを実務で使っていくと書いておいて全く一般的なさわりしか書けませんでした。ですが、今回ようやくちょっと実際に使っていく上で約に立ちそうな事を書いて行きたいと思います

### Helidonプロパティとは
前回の記事でも、port番号の件でちょっと触れたのですが、Helidonが稼働する上でいくつかの事前定義プロパティ（プレフィックスプロパティ）と、ユーザが自分で自由に定義できるカスタムプロパティを定義することができます。
ファイルは、/src/main/resources/META-INFフォルダにある「microprofile-config.properties」にスタンザ形式(プロパティ=値)で書いていく感じです

#### 事前定義プロパティについて
Helidonがデフォルトで用意しているWebサーバに食わせるプロパティが最低限定義されています。
```
# Microprofile server properties
server.port=8080
server.host=0.0.0.0
```

#### カスタムプロパティについて
開発者が、自分のアプリケーションに取り込むために自由に定義するプロパティです。
例えば、Helidonのサンプルアプリには以下が入っています。
```
# Application properties. This is the default greeting
app.greeting=Hello
```
例えば、これを
```
# Application properties. This is the default greeting
app.greeting=Hello Helidon!
```
のように変更してから、以下コマンドでビルドします。(サンプルアプリはHelloの出方に現在のカスタムプロパティの設定内容(app.greeting=Hello)を前提に自動単体テストが組まれてしまっているのでテストをスキップしないとエラーになります）
```
mvn package -DskipTests=true
```
ビルドしたら、下記コマンドで実行します。
```
java -jar target/myproject.jar
```

ブラウザを開いて、以下URLを入力します。
```
http://localhost:8080/simple-greet
```
結果として、プロパティ設定が結果に反映していることが確認できます。![008.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4094226/bbdd08a6-4f26-492b-95d6-3b4642e7169e.jpeg)

### 現実的な話として、プロパティを設定するたびにビルド・デプロイ・再起動が発生するのはどうなのか
と考えるのが普通でしょう。例えば環境ごとにHelidon設定値を変更しながら稼働させなくてはならない場合、各環境ごとに別々にビルドが必要になるのは結構面倒ですし、ナンセンスであると思います。
### Helidonでは環境変数、シェル変数などで実行時にHelidonプロパティをオーバーライドして動かすことが可能です
たとえば、さきほどのapp.greetの文言を稼働時にオーバーライドしたい場合は、Helidonを起動する前に変数設定を以下のように行います。
Windowsなら
```
set APP_GREETING=KONNNICHIWA! HELIDON!
```
Unix系なら
```
export APP_GREETING=KONNNICHIWA! HELIDON!
```
そして、あとは起動するだけです
```
java -jar target/myproject.jar
```
すると、リクエストURLが同じでも結果が変化していることがわかります
![009.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4094226/b496a4ee-a91f-45ae-9640-bd8e4ac98259.jpeg)

カスタムプロパティだけではなく、事前定義プロパティでも利用可能です。
たとえば、起動するポート番号を変えたくなった場合は以下のようにします。
```
C:\downloaded\myproject>set SERVER_PORT=8090
C:\downloaded\myproject>java -jar target/myproject.jar
```
これでHelidonが起動しますので、アクセスするportが8090になっていることが確認できます。
![010.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4094226/a9c326af-fd52-40ec-8476-9463ccaf7f92.jpeg)

### 環境変数・シェル変数に設定する変数名について
もうすでに上記のサンプルでお気づきのことと思いますが、Helidonプロパティ→環境変数への変換は以下のルールで行います。

①設定値を全部大文字へ
②「.」を「_」に置き換え
で変換した値を設定すればOKです。例えばserver.portだったらSERVER_PORTですね
長い場合でもこのルールを適用します。
aa.bb.cc.dd.ee.ff→AA_BB_CC_DD_EE_FF

今回は、Helidonプロパティのオーバーライドについて書きましたが、次回は、企業アプリとしてデプロイする場合に必ず求められるSecureなHelidon環境についてちょっと書いてみたいと思います。
AI様に祈る前に 〜立ち返りたい決定論〜

**なんでもかんでも生成AIに任せるな。**

生成AIは、創造的・あいまいなタスクに強い。一方、ルールが明確で、入力が同じなら出力も同じ「決定論的」なタスクは、従来のプログラムで処理すべきだ。
にもかかわらず、最近「このタスク、生成AIでやらせればいいんじゃね？」という声をよく聞く。

でも、ちょっと待ってほしい。

生成AIは万能じゃない。従来のプログラミングの方が向いていることも全然ある。
そこを一旦冷静に考えてほしい。

## ハンマーしか持たない人間は、ネジすらぶっ叩こうとする

生成AIは確かに便利だ。だが、何にでも使っていいわけじゃない。
決定論的に処理できるものは、Pythonなりで書いた方がいい。生成AIを使う必要はない。

たとえばこんな話があるかもしれない。

> 「いまExcelマクロで動いてるCOBOLシステム用テストデータ作成ツールを、生成AIでやらせたい」

やめておけ。それで動いているなら、そのまま使えばいい。無理に置き換える必要はない。

「生成AIを使わないと時代遅れな気がして不安」
「生成AIを使えば、今よりもっと良くなるかもしれない」

その気持ちはわかる。
けれど、使うこと自体が目的になった瞬間、それは道具ではなく祈りになる。

## Excelマクロが「嫌」？

なにが嫌なのかよくわからないな。
動作要件を満たしていて、業務として成立しているなら、それはそれで「正しい」。どれだけレガシーであっても。

「なんとなく嫌」みたいな雑な感情でシステムを変えようとするな。もし変えるのであれば、まずその“嫌な理由”を言語化しろ。ペインポイントを明確にするところから始めよう。無駄にタスクを増やしてはならない。

保守性に難がある？そういうことも確かにあるかもしれない。ならばPythonでリプレイスすればいい。
**生成AIに置き換える理由にはならない。**

## 「元データがExcelだから」？

なるほど。であれば尚のこと現状のExcelマクロのままでいいんじゃないか？

それでもPythonにしたいのであれば、ExcelをCSVやJSONなど、構造化されたデータ形式に変換するところから始めよう。

「変換しようにもセル結合があるから難しい」？
「JSONは印刷に不向き」？

それならまずフローを見直せ。**見た目に意味を持たせるな。構造に意味を持たせろ。**
どうしてもExcelが欲しいなら、JSONからExcelを作るフローを組め。

## 生成AIの使い所を間違えるな

どうしても生成AIを使いたいなら、「ツール呼び出し分類器」として使え。

「どの処理を呼び出すか」をAIに任せ、**処理自体はPythonなどの決定論的なコードで行う**。これが生成AIとの健全な付き合い方だ。

---

生成AIは便利だ。
だが、**道具には使いどころがある**。

闇雲に使うな。目的と手段を取り違えるな。
火を盗んだプロメテウスに倣え。だが、火に跪くな。
【AWS / IAM 】MFA（多要素認証）を有効化する（パスキーまたはセキュリティーで設定）


# 概要
1つ前の記事[【AWS】IAMユーザーにサインインできない。 | Qiita](https://qiita.com/Ryuki4648/items/1fc4f97e06191f214750)でIAMユーザーにログインができました。

次はMFA（多要素認証）の有効に進みます。
**「パスキーまたはセキュリティーで設定」** する方法で実施しています。

# MFA有効化の流れ

1.　IAMユーザーにログイン

2.　IAM ＞　アクセス管理　＞　ユーザー　にアクセス

3.　自分のユーザー名を探す
※自分のユーザー名（メールアドレス）が見つからないな、と思っていたら2ページ目にあった。

MFAを設定していないので「-」になっています。
設定済のユーザーは「仮想」や「パスキー」と表示されています。

![iam_mfa01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1104075/d0c12559-a49f-49b7-a805-001b61848c77.png)
<br>

4.　自分のユーザー名を押下
<br>

5.　「セキュリティ認証情報」タブを押下
　
![iam_mfa02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1104075/ff6ff69b-6b4e-4a2e-ba8d-5626fe9f46c8.png)

<br>

6.　「MFAデバイスの割り当て」を押下

![iam_mfa03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1104075/9736ede8-cf03-419e-9b0f-b84089a43fb9.png)

<br>
7.　MFAデバイスを選択
「認証アプリケーション」を使おうとしたのですが、
うまくいかなかったので「パスキーまたはセキュリティキー」を選択し、「次へ」を押下

![iam_mfa04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1104075/1724a23b-d13f-4288-85c9-e780d92ce9e7.png)

<br>
8.　「ログインするパスキーを作成しますか？」というポップアップが表示されるので、「作成」を押下

![iam_mfa05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1104075/cac10279-bc8b-49aa-8e84-1dc674670ad5.png)

<br>
9.　「リカバリPINの作成」が表示されるので、PINを入力して「確認」を押下

![iam_mfa06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1104075/7be446e9-b891-47a0-8377-3312e50aa801.png)

<br>
10.　MFAの有効化が完了
緑色のスナックバー「Passkey MFA device assigned」が表示されます。

![iam_mfa07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1104075/039572ae-cb7f-45e7-bc4e-65bdd6d51841.png)

<br>
11.　ユーザー一覧に戻り、MFA「パスキー」と表示されていることを確認

![iam_mfa08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1104075/7a0d0e64-bcc0-480e-8fe7-db2793896726.png)
ACL（Access Control List）の覚書②　覚書から実用化へ

アクセス
依然作ったファイルは単にファイルa.txtができるだけでしたが、今回はファイル名に日付と時間を用意しました。

１日で何回保存しても秒単位でファイル名が変更していくので上書きしてしまう心配がありません。

（また現在、OneDrive使用なので、フォルダの途中にOneDrive用のフォルダがいます。）

```batchfile
@echo off

:: 管理者権限で再実行する
:: 管理者権限がない場合、管理者権限で再実行する
net session >nul 2>&1
if %errorLevel% neq 0 (
    echo 管理者権限で再実行しています...
    powershell -Command "Start-Process '%~f0' -Verb RunAs"
    exit /b
)

set str_date=%date%
set str_time=%time: =0%

rem フォルダを指定 
set "folder=C:\Users\maedat\OneDrive - 〇〇〇▲▲▲株式会社\ドキュメント\aclfolder" 

:: フォルダ内の全ファイルとフォルダのアクセス権データを収集し、保存
icacls "%folder%" /T /C /save "C:\Users\maedat\OneDrive - 〇〇〇▲▲▲株式会社\デスクトップ\downloads\%str_date:~0,4%_%str_date:~5,2%%str_date:~8%_%str_time:~0,2%%str_time:~3,2%_%str_time:~6,2%.txt"
```

①こちらはアクセス権を過去に戻すbatchで特定のフォルダ内にたまったACLのテキストファイルを番号を新しいファイルから採番して、表示
②採番された番号を入力して過去のアクセス権を指定番号のファイルを読み込んで展開するという仕組みに変更しました。


```batchfile
@echo off
:: 管理者権限で再実行する
net session >nul 2>&1
if %errorLevel% neq 0 (
    echo 管理者権限で再実行しています...
    powershell -Command "Start-Process '%~f0' -Verb RunAs"
    exit /b
)
setlocal enabledelayedexpansion

rem フォルダを指定 
set "folder=C:\Users\maedat\OneDrive - 〇〇〇▲▲▲株式会社\デスクトップ\downloads" 

rem フォルダ内のファイル一覧を表示
echo ファイル一覧:
set i=1
for %%f in ("%folder%\*.*") do (
echo !i!. %%~nxf
set "file!i!=%%f"
set /a i+=1
) 

rem ユーザーにファイル番号を選ばせる
set /p choice=番号を選んでください: 

rem 選択されたファイルを変数にセット
set "selectedFile=!file%choice%!"

:: 保存したアクセス権データを復元
cd "C:\Users\maedat\OneDrive - 〇〇〇▲▲▲株式会社\ドキュメント"
icacls .\ /restore "%selectedFile%" /C


if %errorLevel% neq 0 (
    echo アクセス権データの復元に失敗しました。
) else (
    echo アクセス権データの復元に成功しました。
)
```

説明書き

>参照[バッチファイルの基本的な書式と考え方]
https://qiita.com/go1101/items/a2df957120b709b94273

>バッチファイル入門
>https://batchfile.hideharublog.com/batchfile-environmental-variables/

>環境変数の設定方法（Windows）
https://sukkiri.jp/technologies/os/windows/env_setting.html


## 遅延環境変数の使用を宣言する

バッチファイルには **環境変数の即時展開**という特徴があり、環境変数が読み込まれた時点で値を確定してしまいます。

■環境変数とは

まず、環境変数とは、OSに保存するさまざまな設定値をいいます

Windowsには・・・

（１）システム環境変数
（２）ユーザー環境変数

の２つ用意されています。

PCを利用するすべてのユーザーが共有して利用する値が記録されています。（１）
ユーザー環境変数には、それぞれのユーザーごとに個別の設定が記録されています。（２）

よく使われる環境変数として、プログラムがインストールされた場所を示す「Path」や、一時保存ファイルの保管場所を示す「TEMP」などがあります。システム環境変数とユーザー環境変数の両方にこれらの設定値が保存されているので、同一のPCを利用するユーザー全体や、ある特定のユーザーそれぞれで「Path」や「TEMP」を使い分けることができます。

①![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960935/5fd9e791-5583-0bdf-ab4e-1917db6cbcc4.png)

②![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960935/c4d10033-5484-d27e-f42f-2d9c50da7368.png)

③![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960935/7cd3a8c4-10bc-be21-dd64-f031e6cffd9b.png)


④![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960935/450f95c0-3582-1799-3407-ffa4732551af.png)

⑤![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960935/193615d0-7e88-4fd5-055f-d1b208288746.png)




環境変数の即時展開を防ぐためには遅延環境変数を使用します。

    setlocal enabledelayedexpansionを定義する
    変数を%ではなく!で囲む

```batch
@echo off

①---set hensu_a=ピヨ太

if "%hensu_a%" == "ピヨ太" (
    set hensu_a=ピヨ子
    echo %hensu_a%
)
```

①---set hensu_a=ピヨ太  hensu_aを「ぴよ太」と定義
パソコン初期化時に問われる「TPM」について

PCリセットをしてPCを初期状態に戻す際に、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960935/1eefca0b-d9e9-401b-9ce6-a736b3d88f4a.png)

画像の内容[英語]
A configuration change was requested to clear
this computer’s TPM(Trusted Platform Module)

WARNING:Clearing erases information stored on the TPM.
You will lose all created keys and access to data encrypted by these keys.

Press F1 = Accept
Press F2 = Reject


## 『このコンピュータの TPM を初期化する操作ができます
初期化すると、TPM 上で情報が消去されます。

[日本語訳]
このコンピュータのTPM（トラステッド・プラットフォーム・モジュール）をクリアするための構成変更が要求されました。

警告：クリアすると、TPMに保存されている情報が消去されます。
作成されたすべてのキーと、それらのキーで暗号化されたデータへのアクセスが失われます。

F1キーを押す = 承認
F2キーを押す = 拒否

TMPとは暗号化で利用する鍵を安全な場所で管理するための仕組みで、暗号化された文章などと同じ場所で管理すると鍵と金庫を同じ場所で管理しているのと同じなので、セキュリティ的に問題があると考えられるため鍵を安全な場余で管理する仕組みをいう。
猿でもわかるAIプログラミングシリーズ 🐵💻 初めてのPandas：表データを扱ってみよう


## 「初めてのPandas：表データを扱ってみよう」〜現場で役立つデータ処理の基本〜

---

## 1. はじめに：CSVを触れなければAIは語れない

機械学習やデータ分析を行う上で、避けては通れないのが「表形式データ（Tabular Data）」の扱いです。特にCSVやExcelなど、実務では多くの業務データが\*\*“表”として保存\*\*されています。

そんな時に強力な武器になるのが、Pythonのデータ操作ライブラリ **Pandas** です。

本記事では、データ分析未経験者でもすぐに使えるように、Pandasの基本機能と実務での使い方を、**手を動かしながら学べる形式で**解説します。

---

## 2. Pandasとは？何ができるの？

Pandasは、Pythonでデータの読み込み・加工・分析を行うためのライブラリです。

### 主な特徴

| 機能              | 説明                |
| --------------- | ----------------- |
| DataFrame       | 行と列を持つ“表形式”のデータ構造 |
| CSV, Excelの読み書き | データの入出力が簡単        |
| 集計・フィルタ         | SQLのような操作も可能      |
| 欠損値処理           | 欠けたデータへの対応が柔軟     |

このように、Pandasは **AI開発の前処理フェーズやEDA（探索的データ分析）で必須のツール**です。

---

## 3. 実践！Pandasの基本操作

ここからは、実際にコードを書きながらPandasを体験してみましょう。

### 3.1 ライブラリのインポートとデータ読み込み

```python
import pandas as pd

# CSVファイルを読み込む（今回はURLから）
url = 'https://raw.githubusercontent.com/datasciencedojo/datasets/master/titanic.csv'
df = pd.read_csv(url)

# 最初の5行を表示
print(df.head())
```

### 3.2 データの基本情報を確認

```python
# 行数・列数の確認
print(df.shape)

# 各列の型や欠損情報
print(df.info())

# 統計量の表示（平均、中央値、標準偏差など）
print(df.describe())
```

### 3.3 欲しい列だけ取り出す

```python
# 特定の列
print(df['Age'])

# 複数列
print(df[['Age', 'Fare']])
```

### 3.4 条件に合う行をフィルタする

```python
# 20歳未満の乗客
print(df[df['Age'] < 20])

# 女性で1等船室
print(df[(df['Sex'] == 'female') & (df['Pclass'] == 1)])
```

### 3.5 集計やグループ化

```python
# クラスごとの平均年齢
print(df.groupby('Pclass')['Age'].mean())

# 性別ごとの生存率
print(df.groupby('Sex')['Survived'].mean())
```

### 3.6 欠損値の確認と補完

```python
# 欠損値の数
print(df.isnull().sum())

# Age列の欠損を中央値で埋める
df['Age'] = df['Age'].fillna(df['Age'].median())
```

---

## 4. 現場で役立つTipsと落とし穴

### ✅ 実務でよく使うテク

| 操作     | コマンド例                                     |
| ------ | ----------------------------------------- |
| 並び替え   | `df.sort_values('Fare', ascending=False)` |
| 欠損除去   | `df.dropna()`                             |
| 新しい列追加 | `df['Age_bin'] = df['Age'] // 10`         |
| 重複削除   | `df.drop_duplicates()`                    |

### ❌ よくあるミス

* `df['列名']`と`df.列名`を混同してエラー
* `inplace=True`の挙動で元データが上書きされる
* `.loc`と`.iloc`の使い分けがあいまい
* 欠損値を放置してモデル学習が失敗

---

## 5. 応用編：Pandas + 可視化でEDAに挑戦

Pandasは**matplotlibやseabornと組み合わせて視覚的な分析**にも使えます。

```python
import seaborn as sns
import matplotlib.pyplot as plt

# 年齢と料金の関係
sns.scatterplot(x='Age', y='Fare', data=df)
plt.title('年齢と運賃の関係')
plt.show()

# 性別ごとの生存率
sns.barplot(x='Sex', y='Survived', data=df)
plt.title('性別ごとの生存率')
plt.show()
```

これだけでも、かなり実用的なダッシュボードに近いものができます。

---

## 6. まとめ：PandasはAIの“下地”を支える必須ツール

| 項目    | 内容                           |
| ----- | ---------------------------- |
| 👍 強み | 扱いやすく、学習コストが低い。AI前処理との親和性が高い |
| ⚠️ 弱み | 巨大データには不向き（→PolarsやDaskが必要）  |
| 🚀 展望 | Notebook環境・クラウドでもそのまま活用できる   |

現場では、**モデル構築よりも“データ整備”の時間の方が長い**ことも珍しくありません。
だからこそ、Pandasをマスターすることは、**AI・データエンジニアとしての第一歩**です。

---

## 📎 関連リンク

* [Pandas公式ドキュメント](https://pandas.pydata.org/docs/)
* [KaggleでPandasを学ぶチュートリアル](https://www.kaggle.com/learn/pandas)
* [Polars：Pandasの高速代替](https://www.pola.rs/)

---

📌 次回は「AIにおける「教師あり」と「教師なし」の違いって何？」をお届け予定！
フォローしてチェックしてみてください！
猿でもわかるAIプログラミングシリーズ 🐵💻 Pythonの「if」「for」だけで作る簡単なAIロジック


## 「Pythonのifとforだけで作る簡単なAIロジック」〜ゼロから学ぶ“考えるコード”〜

---

## 1. はじめに：AIって、本当に難しい？

「AIプログラミング」と聞くと、多くの人が「難しそう」「ライブラリ覚えるの大変そう」と思いがちです。でも実は、**AI的な思考の基礎**は、Pythonの`if`と`for`だけでも実現できます。

本記事では、機械学習やディープラーニングを一旦横に置いて、Pythonの基本構文だけで“AI的なロジック”を組む練習をしていきます。
目的は、**複雑な仕組みの前に、まず「考えるロジック」を体験すること**です。

---

## 2. AIロジックとは？人間的判断をコードに落とす

ここでいう“AI的ロジック”とは、以下のような特徴を持つコードを指します：

* 状況に応じて動作が変わる（条件分岐）
* 過去の情報を学びに使う（履歴記録）
* 試行錯誤して改善する（簡易的な報酬設計）

複雑な数学モデルがなくても、こうしたロジックは簡単なPythonコードでも再現可能です。

---

## 3. 実装：ifとforだけで作る迷路脱出AI

### 🧩 テーマ：迷路のゴールを目指すエージェント

迷路のような2次元グリッドの中で、エージェントがゴールにたどり着くプログラムを作ります。

```python
maze = [
    ["S", ".", ".", "#", "."],
    ["#", "#", ".", "#", "."],
    [".", ".", ".", ".", "."],
    [".", "#", "#", "#", "."],
    [".", ".", ".", "G", "#"]
]
```

* `"S"`：Start（開始位置）
* `"G"`：Goal（ゴール）
* `"."`：通れる道
* `"#"`：壁

### 🎯 ルール：

* 上下左右に1マスずつ移動可能
* 壁にはぶつかれない
* ゴールに着いたら終了

---

### 👨‍💻 コード例：最短ではないが「考えて進む」

```python
def find_start(maze):
    for i in range(len(maze)):
        for j in range(len(maze[i])):
            if maze[i][j] == "S":
                return i, j

moves = [(-1, 0), (1, 0), (0, -1), (0, 1)]  # 上下左右

def escape_maze(maze):
    visited = set()
    path = []

    def move(x, y):
        if (x, y) in visited:
            return False
        visited.add((x, y))
        path.append((x, y))

        if maze[x][y] == "G":
            return True

        for dx, dy in moves:
            nx, ny = x + dx, y + dy
            if 0 <= nx < len(maze) and 0 <= ny < len(maze[0]):
                if maze[nx][ny] != "#":
                    if move(nx, ny):
                        return True
        path.pop()
        return False

    sx, sy = find_start(maze)
    if move(sx, sy):
        return path
    else:
        return None

result = escape_maze(maze)
print("ゴールへの経路:", result)
```

---

## 4. 実務TIPS：ルールベースAIを使うときのコツ

### ✅ 現場での使い方例

* **簡易なチャットボット**：キーワードに基づいて返答を切り替える
* **工場ラインの動作判定**：条件分岐で異常検知やアラートを発生
* **ゲームAIの初期ロジック**：ランダム移動から「報酬付き行動」へ

### ❌ よくある失敗例

* `if`が多すぎて保守不能（→関数化で整理）
* 状態をメモしていない（→「履歴」や「報酬」の設計が重要）
* 複雑な条件を一文に詰め込みすぎる

---

## 5. 応用編：簡易報酬付きロジックに進化させる

### 例：ゴールに近づいたら+1点、遠ざかったら-1点

```python
def distance_to_goal(x, y, gx, gy):
    return abs(gx - x) + abs(gy - y)

# ゴール位置の取得
def find_goal(maze):
    for i in range(len(maze)):
        for j in range(len(maze[i])):
            if maze[i][j] == "G":
                return i, j
```

こうした距離ベースの「簡易報酬関数」を導入するだけでも、
AI的な判断の幅がぐっと広がります。

---

## 6. まとめ：まずは「考えるコード」から始めよう

| 観点       | 価値                                 |
| -------- | ---------------------------------- |
| ✅ メリット   | 概念理解に最適／ライブラリ不要／動作が目で追える           |
| ⚠️ デメリット | 実用性には限界あり／大規模には不向き                 |
| 🚀 伸びしろ  | ここからQ-Learning, 強化学習, Agent設計へ発展可能 |

---

## 🧠 最後にひとこと

AIは必ずしもブラックボックスではなく、**ルール・行動・学習の組み合わせ**でできています。
まずはPythonの基本文法を使って、\*\*“思考するコード”\*\*を書いてみませんか？

---

📎 次回は「Jupyter Notebookの使い方＆便利機能ガイド」を予定しています！
フォローして、続きもぜひ読んでみてください 🙌
ハートリーフォック近似の変分原理による導出

ハートリーフォック近似では占有状態による軌道{$\phi_i({\bf r})|i=1,2...N$}によるSingle Slate行列式を試行関数として用意し、ハミルトニアンの期待値である全エネルギーを最小化する。軌道関数の正規直行化
$$\delta_{ij}=\int \phi^*_i({\bf r}) \phi_j({\bf r})d^3r \label{eq1}\tag{1}$$を拘束条件とする。この拘束条件をラグランジュの未定乗数法に用いて全エネルギーを最小化する。

その結果、ハートリーフォック近似での一体ハミルトニアン$H$が定義できて（その組み立て方法からしてHはエルミート）、
$$H \phi_i({\bf r}) =\sum_{j} \lambda_{ij} \phi_j({\bf r}) \label{eq2}\tag{2}$$という方程式を得ることになる。これを上の拘束条件とともに解けばよい。

- ただこう言われても理解しにくいので以下のちょっとした考察が必要である。実際、$\lambda$が一意的に決定されるわけではない。

---
ミソは、式$(\ref{eq2})$が何を表しているか？である。式$(\ref{eq2})$の表すところは、
『$H$は「占有状態の張る空間」を「占有状態の張る空間」に写像すること』である。そう書いている文献がみつかりにくいーどこかには書いてたと思うんだが。すなわち$\lambda$はユニタリ変換の分だけ不定である。

なので、「占有状態の張る空間」を全エネルギー最小になるように決めれば良い。すなわち$H$の固有値固有関数を求めて下から詰めればよい。ハートリーフォック近似は「占有状態の張る空間」を求める理論である.

* こう考えるとハートリーフォック近似におけるエネルギー固有値の役割も明瞭である。

* 独立粒子近似を超えて、平均場近似での励起状態を考えるには基底状態と直行する「占有状態の張る空間」というのが基本になる。

* 不純物散乱(金属中での話ではあるが半導体などでも参考になる）を考えるとき、アンダーソンの直行性定理とユニタリ極限や総和則を理解しておいたほうが良い。アンダーソンの直行性定理は、独立粒子近似で考えればいいのだがその前提としてこういう考察をしておくとありがたみがわかりやすいのではないか、と思う。
 
* 時代がweb化することで情報が失われやすいこともある。copilotは「拡散方程式を変分法で導出してください」というと導出してくれたりします。
📘 Vol.8.13：【Struts2】フィールド単位のエラーメッセージ制御   〜 `<s:fielderror>` / `<s:actionerror>` 徹底使い分け 〜

***※ 本章は「UI制御編（実務向け UI 出し分け・エラー表示制御・再利用設計）」シリーズとなります***

## 🔰 はじめに：UIエラー制御の重要性

入力フォームがある限り、**バリデーションエラーは避けて通れない**もの。  
Struts2では、エラー表示用に次の2つのタグが用意されています：

| タグ | 用途 | 主な表示位置の想定 |
|------|------|----------------------|
| `<s:fielderror>` | フィールド単位のエラー | 各入力項目のすぐ下 |
| `<s:actionerror>` | 全体メッセージ（汎用） | 画面上部など一括表示 |

今回はこの2つのタグを、**「実務のよくある失敗例 → ベストプラクティス」** という形で整理していきます。

---

## ✅ 基本の書き方と違い

### ▶️ `<s:fielderror>`：フィールドに紐づくエラーを表示

```jsp
<s:fielderror />
```
---

- addFieldError("username", "ユーザー名は必須です");

- 結果：そのフォームの name="username" のすぐ下 にエラーが出力される
---

## ▶️ `<s:actionerror>`：汎用的なエラーをまとめて表示
```jsp
<s:actionerror />
```

- addActionError("ログインに失敗しました");

- 結果：画面上部などに表示されるメッセージ一覧

---

### ⚠️ 実務でありがちなNGパターン
### ❌ すべて addActionError() で済ませる

```jsp
if (username == null || username.isEmpty()) {
    addActionError("ユーザー名を入力してください"); // ← UIが不親切
}
```
→ フィールドの下にエラーが表示されず、`何の項目がNGか分かりづらい！`

---

### 💡 ベストプラクティス：フィールドごとに使い分けよう

```java
if (username == null || username.isEmpty()) {
    addFieldError("username", "ユーザー名は必須です");
}
if (password == null || password.length() < 8) {
    addFieldError("password", "パスワードは8文字以上で入力してください");
}
```
### ✅ JSP側
```jsp
<s:textfield name="username" label="ユーザー名"/>
<s:textfield name="password" label="パスワード"/>
<s:fielderror />
```

🔎 ポイント
- エラーが出たフィールドの下に 自動で該当メッセージが表示される

- 視認性・UXが大幅アップ！

---

### 🛠 実務Tips：用途に応じた使い分けパターン

| タイミング        | 使用タグ                | 例                    |
| ------------ | ------------------- | -------------------- |
| 入力項目のチェック    | `<s:fielderror>`    | 必須入力・形式チェックなど        |
| ログイン失敗など全体制御 | `<s:actionerror>`   | 認証NG、セッション切れ、DBエラーなど |
| 成功メッセージ      | `<s:actionmessage>` | 更新完了、登録成功など（おまけで紹介）  |

---

 ### 📌 よくある質問（FAQ）
***Q. <s:fielderror> を書いているのに表示されない！***
- `addFieldError()` で指定した キー名がJSPのname属性と一致しているか チェック！

---

### 🔚 おわりに：UIの丁寧さが“実務力”の差

- エラーメッセージの分かりやすさはUIの信頼感に直結

- 本当に伝えたいことをユーザーに 「一目で分かる形」 で表示することが大切です。

---

### 🧭 参考：この章の全体構成

| Vol  | タイトル                       |
| ---- | -------------------------- |
| [8.13](https://qiita.com/drafts/51e140db17b955714875/edit) | ✅ フィールド単位のエラー表示と全体制御の違い    |
| [8.14](https://qiita.com/juehara-crypto/items/1d1437d0782f3ece08af) | 🔁 入力フォームの共通化・再利用          |
| [8.15](https://qiita.com/juehara-crypto/items/9306b1b0ca0053bd0eb6) | ⚙️ 条件付き表示制御パターン（フラグ・ステータス） |

---

### ✍️ 編集後記
この辺りは ***Struts2 + 実務*** の“入口と奥の境目”。
「使えるタグ」から「使いこなすタグ」へのステップアップに、ぜひ！
【解決策】Oracleアカウントが削除されて過去の試験履歴が見られなくなった話

こんにちは。
今回はOracleの仕様により合格実績を失いかけた経験を残しておこうと思います。
同じ状況に陥った方の参考になれば幸いです。
# 経緯
近々Java SE11 Goldを受験しようと思い、[CertView](https://catalog-education.oracle.com/apex/f?p=1010:26:113243650317615) にアクセス。
オラクル認定試験は2年前に受験したきり受けておらず、CertViewへのログインも丸2年行っていませんでした。

# 状況
「アカウントが非アクティブ化されています。システム管理者に連絡してください。」との表示。
メールアドレスとパスワードは合っているはずですが、念のためパスワード変更しようと試みるも、パスワード変更のメールが届きません。
おかしいな？と思い[ヘルプページ](https://www.oracle.com/jp/corporate/contact/help.html)に飛んだところ、以下の記載が。
>* オラクルのプライバシー・ポリシーに基づき、18か月間連続してログインがない場合、アカウントは削除されます。オラクルのアカウントを維持したい場合は、定期的にログインしてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3310527/3899aa3e-0015-4369-ac5d-a53a2e6d9164.png)

前回のログインから2年が経過していたため、私のアカウントは削除済に。
過去の合格履歴が水の泡……合格証明書もDLしていなかったので、目の前が真っ暗になりました…。

# 解決策
どうにかできないかと模索していたところ、以下の記事に出会いました！

http://blog.livedoor.jp/mazimeakira/archives/85065234.html

>・certviewに紐付けられたメールアドレスで、新規oracleアカウントを取得する
・すると、certviewは何事もなかったかのようにアクセス可能になる

上記を参考に新規アカウントをもとのメールアドレスとパスワードで作成しなおしたところ、
無事試験結果が復活！！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3310527/45710831-08b5-4676-8e45-4b73de9f33c4.png)
すぐに合格証明書をDLしました。

# 最後に
まさか一定期間後にアカウントが削除されるなんて思っていなかったので
焦りまくりましたが、無事元に戻すことが出来て良かったです。
ただこの新規登録してもメアドに紐づく履歴が見られる仕様、セキュリティ的にｈどうなんだ…？とは思いますが(笑)
Oracleアカウントには定期的にログインしておくことをおすすめします！
合格証明書も何かあった時のためにダウンロードしておきましょう。
package.json に勝手に "file:フォルダ名" が復活する原因とその解決法

package.json及び package-lock.json に以下のような記述が勝手に追加される／削除しても復活するという現象に悩まされました：
```
"dependencies": {
  "my-local-package": "file:"
}
```



このような "file:○○" は、ローカルのフォルダを npm パッケージとしてリンクしている状態を意味します。
例えば、ローカルにある my-local-package フォルダをリンクした状態だと、上記のように package.json に自動的に追加されます。

しかし、意図的に削除しても再び勝手に追加されてしまうことがあります。

### 🤔 なぜ勝手に戻ってくるの？
これは、過去に npm link や npm install ../path/to/folder などでローカルパッケージをリンクした履歴が残っており、
そのリンク情報が node_modules や package-lock.json に保持されているためです。

解決方法：npm unlink を使う。

⬇️ 手順
1. package.json と package-lock.json のあるプロジェクトルートに移動
2. npm unlink でリンク解除
```
npm unlink my-local-package
 ```
 3.不要なら node_modules と package-lock.json を削除してクリーンにする（オプション） 

 ```
 rm -rf node_modules package-lock.json
npm install
```
4.package.json から "file:..." の記述を削除

### 📝 補足
- npm unlink は、プロジェクトとローカルパッケージとのリンクを解除するコマンドです。

- リンクされた状態では npm install のたびに package.json が書き換えられることがあります。

- 完全にローカルパッケージを使わない場合は、リンクを解除し、通常の npm パッケージとして扱うのが安全です。
Linux 版 Discord  でボイスチャット音が聞こえない(Linux版0.0.90 の問題)

2025年4月頃から、 Linux 版の Discord でラウンジのボイスが鳴らなくなった。
マイクは使えるし、システム音などは聞こえているのでデバイス設定などの問題ではない。

ここを見ると、 Linux ユーザに共通して起こっている問題のようだ。

https://www.reddit.com/r/discordapp/comments/1jzcbiq/i_can_hear_discord_sound_effects_but_i_cant_hear/

他のサイトを見ても、デグレートとしたり Webブラウザを使ったりと苦労しているようだ。


# 環境

- Ubuntu 24.04
- Flatpak 版 Discord
![Screenshot from 2025-05-20 06-54-57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/61775184-3117-46a8-b4aa-eee97673ac01.png)


以下の記事でインストールしたものです。
「Flatpak 版 Discord を使う(Discord のアップデートを手動でコントロール)」
https://qiita.com/nanbuwks/items/04316e43cdce77dbf5a1



# 原因

Linux の Discord の 0.090 自体に問題が入っているようだ。
今回は flatpak を使っていたので flatoak の操作でより新しいバージョンにすることで解決。

# 解決

```
$ flatpak update com.discordapp.Discord
Looking for updates…


        ID                        Branch   Op   Remote    Download
 1. [✓] com.discordapp.Discord    stable   u    flathub   76.2 MB / 109.9 MB

Updates complete.
```

以下のバージョンで治った。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/c7267873-815b-4b82-8c6f-d738ed1d5e22.png)
「変数が定義されていません」というエラーの対処

### 概要
いままで正常に動作していたExcelファイルのマクロがある日突然「変数が定義されていません」というエラーがでるようになったときの解決方法を示します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15241/75d25501-3822-4699-93e5-4670c5ce70aa.png)
よくある変数の定義漏れや変数のスペルミスなどの「マクロ開発時の問題」はここでは取り上げません。「変数が定義されていません」というメッセージからマクロの実装がおかしくなったと思いがちですが、実はExcelの設定で「ActiveXが無効になっていた」というオチでした。

### 該当するケース
・Excelのシート上にテキストボックスやチェックボックスなど「ActiveXコントロール」を配置している。

### 原因
Excelの設定で「ActiveXが無効化」されていて、マクロからコントロールが参照出来なくなっているため。

### 解決方法
#### １．Excelの「ファイル」メニューをクリックする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15241/3bde96c3-7b3b-498a-9604-c08eef4d1469.png)

#### ２．「オプション」をクリックする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15241/47a6feb3-b9ee-4aff-9634-00420ac31f50.png)

#### ３．「トラストセンター」をクリックする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15241/7664f6a3-f5d4-43fc-9754-4dcf8df8bc61.png)

#### ４．「トラストセンターの設定」をクリックする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15241/aa372cd7-cf0f-41af-83e7-017413b22d40.png)

#### ５．「ActiveXの設定」をクリックして、以下のようにチェックをつける
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15241/56766e59-aeaf-469a-a8a0-8861dd9c3c0f.png)


#### ６．問題となったExcelファイルを開きなおしエラーが出ないことを確認する
【AWS】IAMユーザーにログインできない。（「アカウントのパスワードの有効期限が切れているか、リセットが必要です」「この操作を実行する権限がない」）

# 概要
IAMユーザー ログイン（サインイン）時にエラーが発生したので、詳細と解決策について記述します。

# エラー発生の流れ
クライアントにIAMユーザーを作成していただき、
「別紙に各ユーザーのパスワードと各種キーなどが記載されているので、
ログイン確認、パスワード変更、MFA有効化をしてください。」と依頼されました。

ログインURLは <font color="#07975F">https: //hoge-test-dev.signin.aws.amazon.com/console </font>のようなものでした。

　↓↓

ログインURLにアクセスしました。

![IAMユーザー_ログインエラー01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1104075/91a27dc3-30fa-43df-bb5a-cd41434aee6b.png)

以下の情報を入力しました。

**アカウントIDまたはエイリアス**
hoge-test-dev（すでに入っていた）

**IAMユーザー名**
hoge-test＠dev.com（自分のメールアドレス）

**パスワード**
Test00hoge

　↓↓
 
「サインイン」を押下

　↓↓

![IAMユーザー_ログインエラー02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1104075/3b768552-f712-4072-92ed-22b3a3f94712.png)

パスワードのリセットで
<font color="#07975F">**「アカウント (0123456789) のパスワードの有効期限が切れているか、リセットが必要です。
続行するには、古いパスワードを確認し、hoge-test＠dev.com の新しいパスワードを設定してください。」**
</font>と表示されました。

一応「古いパスワード」「新しいパスワード」を入力し、「パスワード変更の確認」を押下しました。

　↓↓

![IAMユーザー_ログインエラー03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1104075/cb99e164-271c-4cb3-ac50-032a3ac73913.png)

ここで、
<font color="#DB251A">**「この操作を実行する権限がないか、新しいパスワードが管理者の設定したアカウントパスワードポリシーに準拠していない可能性があります。」**</font>
というメッセージが表示されました。

　↓↓

先方にパスワードをリセットしてもらったものの、同じエラーが出てログインできませんでした。

IAMユーザを見る限り、[IAMUserChangePassword | AWSドキュメント](https://docs.aws.amazon.com/ja_jp/aws-managed-policy/latest/reference/IAMUserChangePassword.html) は付与されているようでした。

# 原因と解決策
**「この操作を実行する権限がないか、新しいパスワードが管理者の設定したアカウントパスワードポリシーに準拠していない可能性があります。」**

→ この「パスワードポリシーに準拠していない」という点が気になります。

ただ、パスワードを「Test00hoge」（10文字）や「Test00hoge!」（11文字）で試しており、英数字＆大文字小文字、記号の条件は満たしています。

試しに「Test00hogefuga」と<font color="#DB251A">**14文字に増やしたらログインできるようになりました。**</font>

---------------------------------------

ただ、「パスワードは8文字以上あるのになぜログインできなかったのか？」と思いました。

ログイン後にIAMのアクセス管理　＞　アカウント設定を見ると、
**パスワードの最小文字数　14 文字**
というカスタムパスワードポリシーが記載されていました。

![qiita_iam_password.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1104075/abf348bd-984b-424b-99b5-1e2f8702b2b9.png)

このポリシーを知らなかったのが原因になります。

# 引用
・[IAM ユーザー用のアカウントパスワードポリシーを設定する | AWSドキュメント](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_credentials_passwords_account-policy.html)
自律型コーディングAIエージェント比較分析(2025年5月時点)

ホスト実行型の自律型コーディングAIエージェントが出揃ってきたので、社内選定するに際し、比較ポイントを簡単にまとめました。各サービスリリース（ベータリリース含む）されたばかりの状態で、今後評価が変わってくると思いますが、2025年5月時点での分析結果をアウトプットします。

**評価基準:**

  * ◎：非常に良い / 包括的に可能
  * ○：良い / 可能
  * △：限定的 / 一部可能 / 条件付きで可能 / 不明瞭な点あり
  * ×：不可 / 不明 / 情報なし

**自律型コーディングAIエージェント比較一覧**

| 項目 | Devin2.0 (Core/Team) | GitHub Copilot Coding Agent | OpenAI Codex (in ChatGPT) | Google Jules | Amazon Q Developer in GitHub |
| ---------------- | ----------------------------------------------------- | --------------------------------------------------------- | ---------------------------------------------------------- | --------------------------------------------------------------- | ---------------------------------------------------------------- |
| **モデル** | △ (Sonnet 3.7組込可能性、詳細非公開) | △ (特定モデル非公開、Chatで複数選択可) | ○ (codex-1/o3, codex-mini-latest/API, o4-mini/CLI) | ◎ (Gemini 2.5 Pro) | △ (Bedrock上複数FM利用、詳細非公開) |
| **モデル学習制御** | ◎ (デフォルト利用せず、Enterpriseデータ完全分離) | ◎ (デフォルト利用せず、GitHub強制) | ○ (ビジネスはデフォルト利用せず、個人は要オプトアウト) | ◎ (デフォルトでプライベート、ユーザーコード学習利用なし) | ○ (Pro/プレビューは利用せず、Freeは要オプトアウト) |
| **ホスト** | ○ (クラウドIDE内VM、並列実行可) | ○ (GitHub Actions一時環境、ホステッドランナー必須) | ○ (OpenAIサーバーサンドボックス、ローカルCLI可) | ○ (Google Cloud VM、非同期実行) | ○ ([GitHub.com/Enterprise](https://www.google.com/search?q=https://GitHub.com/Enterprise) Cloud内で動作、データ処理米国内) |
| **ツール連携** | ○ (独自IDE/Search/Wiki、主要プラットフォーム連携) | ◎ (主要IDE連携、GitHubネイティブ統合、MCPで拡張可) | ○ (ChatGPT UI、GitHub連携、AGENTS.MD) | ○ (GitHub連携、音声チェンジログ) | ○ (GitHub Issues/PR/Actions連携、ブラウザ拡張) |
| **コスト** | △ (Core: 20ドル/月＋ACU変動、Team: 500ドル/月 250ACU含) | △ (Copilot Enterprise/Pro+必須、プレミアムリクエスト/Actions時間消費) | △ (ChatGPT Pro等必須、将来従量課金、API料金あり) | ○ (ベータ無料、日5タスク制限、将来価格設定) | ○ (無料枠あり制限あり、AWSアカウント登録で増量可、Pro Tier月$19) |
| **ガードレール** | ○ (API経由プロンプトカスタマイズ、インタラクティブプランニング)| ◎ (ブランチ保護、人間承認必須、`copilot-instructions.md`) | ○ (`AGENTS.MD`、マルウェア開発拒否、ネットワーク制限) | △ (計画修正可、`.idx/airules.md`のような仕組み不明確) | △ (Actions連携でカスタマイズ可、専用指示ファイル等不明) |
| **シークレット登録** | ◎ (専用Secrets機能、OTP対応、暗号化) | ○ (リポジトリ設定内`copilot`専用環境、MCPシークレットプレフィックス要) | △ (ChatGPT内:セットアップスクリプト経由可能性/公式不明確、CLI:環境変数) | ○ (Google Cloud Secret Manager連携推奨、VMサービスアカウントIAM権限) | × (詳細不明、コードレビューでハードコードシークレット検知機能あり) |

**注記:**

  * この一覧は、提供されたレポートに基づいた2025年第2四半期時点での情報であり、各AIエージェントの機能や料金体系は変更される可能性があります。
  * 「コスト」の評価は、小規模から中規模のシステム開発を想定した場合の初期費用や変動要素を考慮しています。
  * 「ガードレール」は、禁止事項設定や行動制御のカスタマイズ性を評価しています。
  * 「シークレット登録」は、機微情報やAPIキーなどの安全な管理方法の有無と堅牢性を評価しています。

この要約情報が、各AIエージェントの比較検討にお役立ていただければ幸いです。
より詳細な情報や最新の状況については、各ベンダーの公式ドキュメント等をご参照ください。
【超入門】TCP/IP　①概要

# TCP/IPとは
* **TCP**(Transmission Control Protocol)と**IP**(Internet Protocol)の二つのプロトコル。
* IPを利用、通信するときに必要となる多くのプロトコル群の総称。
* OSI参照モデルの1～4層（TCP/IP４階層モデルでは1～3層）で動作する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4092311/224d3971-535f-4e54-aaa9-d0dc38a38e80.png)


# データの送受信
**・送信**
上位のプロトコルから下位のプロトコルにデータを渡していく際に受け取ったデータにヘッダを付与していく。
**・受信**
下位から受け取ったデータのヘッダを理解して上位のプロトコルに渡していく。

**TCP/IPプロトコルの場合**
TCP/IP4階層モデルで見ていくと、、、
第3層のトランスポート層で「TCPヘッダ」を、
第2層のインターネット層で「IPヘッダ」をそれぞれ付与・理解して動作していく。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4092311/fee97395-760f-4a3f-974c-45efdaab24b6.png)

# TCP/IPプロトコルの最大データ量の制限
上位プロトコルのデータサイズは、買いプロトコルのデータサイズにより**制限される**

ex)上位がIP、買いがイーサネットの場合
    IPパケットの最大サイズ = 1500バイト（イーサネットフレームのデータ部分の最大サイズ）
    TCPセグメントの最大サイズ = 通常1480バイト（IPヘッダのサイズによる）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4092311/dfc31b7a-e6ba-48c4-854e-24990599fdf8.png)

:::note info
**FCS**とは？
イーサネットフレームが壊れていないか確認用のフィールドのこと
:::
:::note info
**MTU**と**MSS**
MTU（Maximum Transmission Unit）：1回の通信で送れる最大のデータ量（IPパケットのサイズ）
MTU＝IPヘッダ + TCP/UDPヘッダ + データ

MSS（Maximum Segment Size）：TCPで送れるデータ部分の最大サイズ
MSS＝MTU - (TCP/UDPヘッダ + IPヘッダ)
:::

### MTUの設定
windowsにてMTUの情報を見るには以下のコマンドを使用する
```:cmd
C:\Users\test>netsh interface ipv4 show interface

Idx     Met         MTU          状態                 名前
---  ----------  ----------  ------------  ---------------------------
  1          75  4294967295  connected     Loopback Pseudo-Interface 1
 13          65        1500  disconnected  Bluetooth ネットワーク接続
  9          45        1500  connected     Wi-Fi
 16          25        1500  disconnected  ローカル エリア接続* 1
 17           5        1500  disconnected  イーサネット
  6          25        1500  disconnected  ローカル エリア接続* 2
```

あまり使わないとは思いますが、、、
MTUを設定するには以下のコマンドを使用します
```:cmd
netsh interface ipv4 set interface 9 mtu=1500
```
🌟 Vol.8.9〜8.12 総まとめ：Struts2タグライブラリ応用編【UI制御・構造最適化・共通化】

Struts2タグライブラリの実務活用において、「**条件付きUI制御／見た目の統一／共通レイアウト化**」といった応用テクニックを体系的に学べるシリーズ Vol.8.9〜8.12 をここに集約！

> ✨「初級を卒業し、実務で通用する画面設計をしたい方」向けの応用編まとめです！

---

## 👥 想定読者

- Struts2タグの基礎（`<s:if>` など）を理解している方  
- 保守性・再利用性を意識したUI設計に興味がある方  
- 実務プロジェクトでの「共通化・整理整頓されたJSP」構築を学びたい方

---

## 📚 各記事リンクとテーマ概要

| Vol | タイトル | 内容のポイント |
|-----|----------|----------------|
| [📘 Vol.8.9](https://qiita.com/juehara-crypto/items/0d1e09c5241a2a1c9f60) | UIを条件で自在に制御！〜 `<s:if>` / `<s:else>` / OGNL活用 〜 | 状態や権限による動的出し分け、見やすい条件分岐 |
| [📗 Vol.8.10](https://qiita.com/juehara-crypto/items/10f85829a2e56e889cb3) | タグの自作入門 〜 カスタムJSPタグライブラリ基礎 〜 | 再利用可能な部品化でUI開発の効率を劇的改善 |
| [📗 Vol.8.11](https://qiita.com/juehara-crypto/items/4793c85e0900a6fea4c8) | 見た目を整えろ！〜 タグ構造のパターン化Tips 〜 | タグの入れ子・定型化でスタイリッシュなJSPに |
| [📗 Vol.8.12](https://qiita.com/juehara-crypto/items/bbe57cc81a3834704c4c) | 共通レイアウト設計術 〜 `<%@ include %>` 活用と部品化 〜 | ヘッダー・メニュー・フッターの共通化と構造整理術 |

---

## 🔧 このシリーズで身につく実践力

- ✅ UI出力の条件制御・分岐パターンの整理術
- ✅ 再利用性を高める構造設計（タグのテンプレート化）
- ✅ チーム開発でも通用する「共通レイアウトの型化」

---

## 🪜 次のステップへ：Vol.8.13〜（UI制御 実務テクニック集）

この Vol.8.9〜8.12 応用編のあとには、さらに実務度の高い**UI制御パターン集（Vol.8.13〜）**が続きます！

- ⚠️ エラーメッセージ表示／カスタマイズ
- 🔁 フォーム再表示（値保持と状態復元）
- 🧠 状態別の表示要素制御（ログインユーザー別など）

---

## 🧭 関連リンク（全体像の把握に）

- 📘 [Vol.1〜7 総まとめ：Struts2プロジェクトの軌跡と学び](https://qiita.com/juehara-crypto/items/251fea796d8f9fd0532e)
- 📘 [Vol.8.0〜8.12 総まとめ & 実務逆引きリファレンス](https://qiita.com/juehara-crypto/items/60fde06e887bc420520d)

---

🎯 実務に強い Struts2 開発者を目指して、UIまわりの「整理・共通化・簡潔化」スキルをアップデートしていきましょう！
71歳の... ESP32-S3のシリアル通信が動かなくて（？）困った。結果、解った事、考えた事など。

　**ESP32-S3**でシリアル通信してみたら、あれ、シリアルモニタに文字が出ないんだけど...動いてない？このボード息してないの？普通に使えてたはずなんだけど。
　三年ほど前に秋月電子から購入したものです。現在はこのバージョンではなく、後継品に代わっているようです。

 https://docs.espressif.com/projects/esp-dev-kits/en/latest/esp32s3/esp32-s3-devkitc-1/user_guide_v1.0.html

 ![ESP32-S3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3189926/6250974a-fd08-47fc-9427-5285815c8933.jpeg)
![ESP32-S3_2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3189926/2f1ad188-ba1f-416e-81be-c4d684beea05.jpeg)

Windows ターミナルで `esptool flash_id`と打ち込んでみるとこうなります。

![S3_espTool.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3189926/9c94542e-8ed1-4fef-8850-f1122de7f29a.jpeg)

ボードに問題はなさそう。さて、どうしたものか。ネットに情報がありますが、よくわからない。最もシンプルな例で試してみます。

```c:SimpleSerial.ino
void setup() {
  Serial.begin(115200);
  Serial.println("Hello World!");
  pinMode(4, OUTPUT);
  analogWrite(4, 200); // LED(4) ON
}

void loop(){;}
```
LED(4)は点灯しますが、`"Hello World!"`が表示されません。ふと気付きました。いつも使用している`Arduino IDE 2.3.6`のデフォルトなのか

    ツール　-> USB CDC On Boot:"Enabled"
となっており、これが理由でした。`Disabled`にしてやれば無事に動きます。

----------------------------------------------------------------------
　ついでに、以前の投稿と被るのですが改めて自分のメモとして、「シリアル通信」の「文字列受信」について書き留めておきます。
　UNO、ESP32などに文字列を渡すとき、`serial.readString`が便利です。そのとき、大きく分けて２つの仕方があると思います。
　一つはhttps://rabbitprogram.com/archives/1325
に紹介されている

```c:
//参考サイト：http://ch.nicovideo.jp/yugata/blomaga/ar1177727
void setup() {
  Serial.begin(115200);
}
int i = 0;
void loop() {
  if (Serial.available() > 0) {
    String str = Serial.readStringUntil(';');  //「;」を検出したら終了
            // ';'でなくても動作する模様。単なる改行でも認識。
    //ここは、シリアル受信したときに実行する
    Serial.printf("Input string : %s", str);
    str = "";
  }

  //ここは、何もシリアル受信していないときに実行する
  Serial.printf("loop %d\n\r", i++);
  delay(1000);
}

```
の方法。これは、シリアル受信が無くても１秒ごとにloop回数をカウントされ、動き続けていることがわかります。
　２つ目は私がよく使う次の方法です。

```c:
void setup() {
  Serial.begin(115200);
}
int i = 0;
void loop() {
  String str="";
  while( (str=Serial.readString()) == 0)
  {
    Serial.printf("Nothing %d\n\r",i++);// wait timeout.
  }
  i = 0; 
  str.trim();                        // remove any \r \n whitespace at the end of the String
  Serial.printf("Input String : %s\n\r",str);
  delay(1000);
}
```
こちらはシリアル受信を待ち続け「while loop」しており、そのあとのコードは実行されません。受信すると次に進み「i = 0」にリセット、入力された文字列が表示されたりします。
　どちらも「loop」することに違いはありませんが、目的に応じて使い分けられると思います。昔のシングルタスクPCにおけるコマンドプロンプトのような動作が後者でしょうか。また一つ困ったことが分かりました。単一のキーを連打して入力すると正しく読み取ってくれません。普通このような文字列入力はしないと思いますが。
　最後までお付き合いいただきありがとうございました。
AWSのCodeCommitが開けない事象の解決法（AWS:500 サーバーエラー）

他のサービスにはアクセスできているが、CodeCommitを開いた際にAWS:500サーバーエラーと表示され、画面に以下の画像が出た際の解消法です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1946734/3a80005b-5d3c-445e-b426-8de1124b75e9.png)

<h2>結論</h2>

マルチセッションサポートをオフにしてください。
画面右上のアカウントIDを選択し、マルチセッションサポートをオフにし、一度サインアウトを行ってください。
マルチセッションサポートをオフにした状態でもう一度サインインすれば、CodeCommitに接続できるはずです。

<h2>原因</h2>
セキュリティポリシーが原因？
CodeCommitのセキュリティポリシーが複数のセッションを同時に受け付けないように設定されている可能性があるかもしれません。このような設定があると、新しいセッションがブロックされているのでは？
CSS変数

CSS変数とは、**変数を使って、色やサイズなどの値をまとめて管理できる機能**です。

# 定義
## CSS変数の宣言
```CSS
:root {
  --my-color: blue;
}
```
- `:root`は HTML全体に適用される特別な擬似区タス（グローバル変数みたいな感じ）
- 最初に`--`とつける
- 大文字と小文字が区別される

## CSS変数を使う
```CSS
h1 {
  color: var(--My-color, orange);
  border-bottom: 3px solid var(--my-color);
}
```
- `var(--変数名)`で変数を読み込んで使う
- `,XX`で宣言されていない場合の初期値を設定できる

## 注意点
- CSS 変数はプロパティの値に使えるのであって、プロパティ名のほうには使うことはできません。
```CSS
プロパティ名: プロパティ値
```

- あとから単位を追加することができない
```CSS
:root {
 --my-margin-left: 32;
}
```
上記のようにCSS変数を宣言し、単位を追加してもうまくいかない。
```CSS
h1 {
  margin-left: var(--my-margin-left)px;
}
```
**解決方法1：宣言時に単位を設定しよう！**
```CSS
:root {
  --my-margin-left: 32px;
}
```

**解決方法2：`calc`関数を使用しよう！**
```CSS
:root {
  --my-margin-left: 32;
}

h1 {
  margin-left: calc(var(--my-margin-left) * 1px);
}
```

# テーマカラーの設定

- `200`に設定
```CSS
:root {
  --my-hue: 200;
}
```

- 変数を使うだけ！
```CSS
body {
  background: hsl(var(--my-hue), 40%, 95%);
}
```

- 真反対の補色も簡単
```CSS
 background: hsl(calc(var(--my-hue) + 180), 50%, 50%);
```