OmniAICreator/Qiita-1.07M huggingface dataset:
CCNA勉強会＃1　サブネットの理解

## はじめに
この記事は、私が主催している『CCNA頑張ろうの会』のパケトレを使ったオリジナル問題を解説するための記事になります。ファイルはリンクからダウンロード出来ますので、
チャレンジしてみてください。

https://drive.google.com/file/d/1zOfYXOq2QQjJLoaW88ESoePsphbJOXJq/view?usp=drive_link


![スクリーンショット 2025-05-16 212234.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3715252/9069d2ee-e095-48d4-95f0-07bf973db8dd.png)

### 問題　

RT1のGi0/0とRT2のGi0/0に以下の条件を満たすアドレスを割り振り、PC-AからPC-Bにpingを成功させてください。ただし、他に必要な設定はすでに完了できているものとする。

条件

範囲

10.0.0.64/26　

RT1はホストに割り振れる最小のアドレスを使用する
RT2はホストに割り振れる最大のアドレスを使用する
設定が完了したらstartup-configにrunning-configにコピーすること。

## 解説

解き方の手順　

①　10.0.0.64/26をサブネット表記を求める
②　上記のネットワークが取りうるホストのアドレス範囲を求める
③　1番小さいホストアドレスと1番大きいアドレスを求める
④　各インターフェイスに求めたアドレスをそれぞれ適用する
⑤　pingする

####
①　第3オクテットと第4オクテットの境目が/24なので、/26は第4オクテットの8ビット目と7ビット目に1が入りその合計値は192になる。よってサブネットは255.255.255.192になる

②　アドレス範囲は
ネットワークアドレス+ホスト部が全部0の時
～
ネットワークアドレス+ホスト部の値が全部1の時

よって10.0.0.64/26の場合は

10.0.0.64
～
10.0.0.127

となる。ただし、ブロードキャストアドレスとネットワークアドレスはホストに割り振れないため、ホストに割り振れるアドレス範囲は

10.0.0.65
～
10.0.0.126  となる。

③　②よりRT1のGi0/0には
10.0.0.65
RT2のGi0/0には
10.0.0.127を適用する。


RT1>en
RT1#conf t 
RT1(config)interface gigabitethernet 0/0
RT1(config-if)ip address 10.0.0.65 255.255.255.192
RT1(config-if)no shutdown
RT1(config-if)end
RT1#copy running-config startup-config

RT2>en
RT2#conf t 
RT2(config)interface gigabitethernet 0/0
RT2(config-if)ip address 10.0.0.126 255.255.255.192
RT2(config-if)no shutdown
RT2(config-if)end
RT2#copy running-config startup-config

⑤　PC-Aをクリックしデスクトップタブからコマンドプロンプトを選択し以下のコマンドを入力
ping 192.168.10.1  

# 各RTのRunning-config

### RT1

Building configuration...

Current configuration : 681 bytes
!
version 15.1
no service timestamps log datetime msec
no service timestamps debug datetime msec
no service password-encryption
!
hostname RT1
!
!
!
!
!
!
!
!
ip cef
no ipv6 cef
!
!
!
!
license udi pid CISCO1941/K9 sn FTX15249DW7-
!
!
!
!
!
!
!
!
!
!
!
spanning-tree mode pvst
!
!
!
!
!
!
interface GigabitEthernet0/0
 ip address 10.0.0.65 255.255.255.192
 duplex auto
 speed auto
!
interface GigabitEthernet0/1
 ip address 192.168.1.254 255.255.255.0
 duplex auto
 speed auto
!
interface Vlan1
 no ip address
 shutdown
!
ip classless
ip route 192.168.10.0 255.255.255.0 10.0.0.126 
!
ip flow-export version 9
!
!
!
!
!
!
!
line con 0
!
line aux 0
!
line vty 0 4
 login
!
!
!
end

### RT2

Building configuration...

Current configuration : 681 bytes
!
version 15.1
no service timestamps log datetime msec
no service timestamps debug datetime msec
no service password-encryption
!
hostname RT2
!
!
!
!
!
!
!
!
ip cef
no ipv6 cef
!
!
!
!
license udi pid CISCO1941/K9 sn FTX15245JVO-
!
!
!
!
!
!
!
!
!
!
!
spanning-tree mode pvst
!
!
!
!
!
!
interface GigabitEthernet0/0
 ip address 10.0.0.126 255.255.255.192
 duplex auto
 speed auto
!
interface GigabitEthernet0/1
 ip address 192.168.10.254 255.255.255.0
 duplex auto
 speed auto
!
interface Vlan1
 no ip address
 shutdown
!
ip classless
ip route 192.168.1.0 255.255.255.0 10.0.0.65 
!
ip flow-export version 9
!
!
!
!
!
!
!
line con 0
!
line aux 0
!
line vty 0 4
 login
!
!
!
end
Aurora PostgreSQL 15.10 がLTSに！

Aurora PostgreSQL をご利用の皆様、こんにちは！インサイトテクノロジーの松尾です。

気づいたら Aurora PostgreSQL の **15.10** が、待望の **Long-Term Support (LTS)** リリースとして設定されていました！

つい先日まで LTS は Aurora PostgreSQL 14 にまでしか設定されていなかったので、LTS の乗り換え先を不安に思われていた方も多いのではないでしょうか。より新しい機能 enhancements を享受しながら、長期にわたる安定した運用を実現できるこの機会を、ぜひご検討ください。

## LTS (Long-Term Support) とは？

LTS (長期サポート) バージョンは、セキュリティアップデートや重要なバグフィックスが長期にわたって提供されるため、システムの安定性とセキュリティを重視するお客様にとって最適な選択肢です。計画的なメンテナンスサイクルで、安心して長期的なシステム運用を行うことができます。

## Aurora PostgreSQL 15.10 の主な特長

Aurora PostgreSQL 15.10 は、パフォーマンスの向上、セキュリティ機能の強化、そして PostgreSQL 15 の新機能を取り込んでいます。

* **パフォーマンスの向上:** クエリの最適化や並列処理の改善により、より高速なデータ処理を実現します。
* **セキュリティの強化:** 最新のセキュリティパッチ適用により、常に安全なデータベース環境を維持します。
* **PostgreSQL 15 の新機能:**
    * **`MERGE` コマンド:** より効率的なデータ統合処理を可能にします。
    * **JSONB の機能強化:** JSON データの操作性が向上し、より複雑なデータ構造を扱えるようになります。
    * **新しい統計情報:** クエリプランの最適化に役立つ詳細な統計情報を利用できます。

## LTS リリースがもたらすメリット

Aurora PostgreSQL 15.10 が LTS となったことで、以下のメリットが期待できます。

* **長期的な安定運用:** 長期間にわたるセキュリティアップデートとバグフィックスにより、安心してシステムを利用できます。
* **計画的なメンテナンス:** 定期的なメンテナンスサイクルに沿って、計画的にシステムのアップデートを実施できます。
* **新しい機能の利用:** PostgreSQL 15 の新機能を、長期サポートの恩恵を受けながら利用できます。

## まとめ

Aurora PostgreSQL 15.10 の LTS リリースは、長期的な安定運用と最新機能の活用を求めるお客様にとって、非常に魅力的な選択肢となります。この機会にぜひ、Aurora PostgreSQL 15.10 への移行をご検討いただき、より高性能で安定したデータベース環境を実現してください。

### 【宣伝】移行をご検討中のお客様へ

現在 Aurora PostgreSQL の旧バージョンをご利用のお客様にとって、バージョン 15.10 LTS への移行は、システムの安定性と最新機能の利用を両立させる絶好の機会です。一方で、データベースのメジャーバージョンアップにおいては、しっかりとしたバージョンアップテストが欠かせません。テストの網羅性・効率性をあげるために、Insight SQL Testing などのバージョンアップテストツールも是非ご検討ください。

https://qiita.com/takumats/items/e100370373dfa02e3164

https://www.insight-tec.com/products/sqltesting/

## 参考情報

詳細については、以下の AWS の公式ドキュメントをご参照ください。

* [Amazon Aurora PostgreSQL のアップデート](https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/AuroraPostgreSQL.Updates.html)
* [Aurora PostgreSQL 長期サポート (LTS) リリースの使用](https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/AuroraPostgreSQL.Updates.LTS.html)
TweetReply はツイートを自動返信するための Chrome プラグインです。

TweetReply はツイートを自動返信するための Chrome プラグインです。

この AI スマート返信ビルダーを使用して、Twitter でのやり取りの効率を向上させましょう。
AI テクノロジーにより高品質の返信コンテンツを自動的に生成し、時間を節約してファンのインタラクション率を向上させます。
このソーシャルメディアアシスタントは、日常業務でもブランドプロモーションでも、ツイートの内容に基づいて適切な返信プランをインテリジェントに推奨し、高頻度のインタラクションシナリオに簡単に対応できます。
コンテンツの最適化とパーソナライズされたカスタマイズをサポートし、影響力を迅速に拡大し、Twitter アカウントの安定した成長を実現します。
セルフメディア運営者、ブランド、ソーシャルメディア管理者に適しており、ソーシャルメディア運用効率向上に必須のツールです。
AIがもたらす新しいコンテンツ制作方法を今すぐ体験してください！
https://www.tweetreply.com
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4083312/f869bd75-7de1-4a10-9b09-00ca7cccc601.png)
Glivenkoの定理の証明とCPS変換との関係

本稿で断り無しに「古典論理」といったらそれは古典命題論理であり、断り無しに「直観主義論理」といったらそれは直観主義命題論理を意図しています。

---

古典論理と直観主義論理をつなぐ「Glivenkoの定理」。  
その証明の流れと、プログラム変換手法として知られる CPS変換（継続渡し形式）との驚くべき関係を紹介します。

---

## Glivenkoの定理とは？

**命題論理におけるGlivenkoの定理の主張：**

> φ が古典論理 LK で証明可能ならば、その二重否定 ¬¬φ は直観主義論理 LJ でも証明可能。

これは、形式的には次のように表されます：

```
Γ ⊢ φ（LKで証明可能） ⇒ Γ ⊢ ¬¬φ（LJで証明可能）
```

---

## 証明の全体構造

Glivenkoの定理の証明は以下の2方向があります。

1. **直観主義 ⇒ 古典**（容易）  
   - ¬¬φ が直観主義論理で証明可能なら、φ は古典論理でも証明可能。

2. **古典 ⇒ 直観主義**（本質的部分）  
   - φ が古典論理で証明可能なら、¬¬φ が直観主義論理で証明可能。

---

## 古典から直観主義への証明ステップ

証明は、古典論理の証明図に対する**構造的帰納法**で行われます。  
最終推論規則によって場合分けします。

### ケース例：

- **含意導入（→）**  
  ```
  古典: Γ ⊢ A → B  
  ⇒ 直観: Γ, A ⊢ ¬¬B  
  ⇒ ¬¬(A → B)
  ```

- **否定導入（¬）**  
  ```
  古典: Γ, A ⊢ ⊥  
  ⇒ 直観: Γ ⊢ ¬A
  ```

- **基底ケース（公理）**  
  - φ が恒真であれば、¬¬φ も LJ で証明可能。

---

## CPS変換との関係

### CPSとは？

CPS（Continuation-Passing Style）は、関数が値を返すのではなく、「次に何をするか」（継続）に処理を渡すスタイルです。

```js
// 通常の関数
function f(x) {
  return x + 1;
}

// CPSスタイル
function f_cps(x, cont) {
  cont(x + 1);
}
```

---

## Glivenkoの変換と CPS の対応

論理における二重否定は、CPSにおける**「継続の安全性」**に対応します。

| 論理表現 | 意味 | CPS的意味 |
|---------|------|------------|
| φ       | 計算の成功 | 結果が得られる |
| ¬φ = (φ → ⊥) | 例外 | φが走れば矛盾（エラー） |
| ¬¬φ = ((φ → ⊥) → ⊥) | φに矛盾がない | 安全な継続処理が可能 |

---

## 結論

- Glivenkoの定理は、**古典論理を構成的に扱うための鍵**となる理論です。
- CPS変換との対応は、**Curry-Howard同型対応**（論理と計算の一致）を具体化した好例です。
- 証明論・型理論・計算機科学の交差点に位置するテーマとして、今後も応用が期待されます。

---

## ✍ 参考キーワード

- Glivenkoの定理
- 直観主義論理
- CPS変換
- Curry-Howard対応
- 証明論
- 継続


---

## 🎥 解説動画：Glivenkoの定理をもっと深く知りたい方へ

本記事の内容を動画でさらに詳しく学びたい方のために、YouTubeにて  
**「Glivenkoの定理（グリベンコの定理）の証明・紹介」**という解説動画を公開しています。

[▶️ YouTubeで視聴する（約8分）](https://youtu.be/MrsbbxeK7P0?si=V_Df-C_7Xn4Mhqfi)

- 古典命題論理と直観主義論理の関係性  
- 二重否定翻訳とGlivenkoの定理の具体的な証明  
- 証明論・型理論・計算機科学に通じる思考の楽しさ

などをコンパクトにまとめており、初学者にも理解しやすい構成です。

---

📌 **動画内目次**

```
00:00 アイキャッチ
00:20 はじめの挨拶
00:54 動画の概要
01:22 体系LK, LJ
02:26 グリベンコの定理の主張の紹介
02:56 グリベンコの定理の証明
07:30 余談
07:50 おわりの挨拶
08:10 エンド・クレジット
```

---

🔗 **参考資料とリンク**

- 資料PDF：https://www.quawai.kyoto/pdfs/material_Glivenko.pdf  
- 論計舎ウェブサイト：https://ronkeisha.net  
- お問い合わせ：https://ronkeisha.net/contact/  
- Twitter（論計舎）：[@ronkeisha_info](https://twitter.com/ronkeisha_info)  
- Twitter（川井 新）：[@squawai](https://twitter.com/squawai)
削除についてのまとめ




# 破壊的変更のデプロイメント

+ [Destructive (DELETE) Deployments](https://qiita.com/Keiji_otsubo/items/cb1e67d7206813880a8d)


# オブジェクトの項目を削除する

+ [項目削除を進める手順について](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX00000TiEIM)

:::note
興味深いのは削除対象となる項目のFLSを一旦全て取り除いてみて、影響を見てみるのがいいらしいということです。確かに本当に消してしまうと項目の中身を戻すのは厄介ですので、消す作業をする前にアクセス権を除いてみることは有効でしょう。問題があればアクセス権を戻せばいいですので... 

https://www.reddit.com/r/salesforce/comments/nfabxv/considerations_when_deleting_a_custom_field/

https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000A8sdeSAB
:::
細かすぎるViteのチャンク問題

ViteでJavaScriptプロジェクトをビルドしてみたところ、想定以上に細切れとなりましたが、調整したら緩和できました。

## TL; DR

* ViteはES Moduleネイティブで、ブラウザの`import`を使うような結果を生成する
* コードの過不足がないように分割するので、細かくなりすぎることがある
* Rollup側の`output.experimentalMinChunkSize`で改善可能

## ViteとWebpackの違い

既存のプロジェクトをWebpackからViteに乗り換えたのですが、考え方が大きく異なりました。

Webpackは、CommonJS全盛期の2014年に初版が作られたソフトウェアで、のちにES Moduleにも対応してきたとはいえ、モジュール管理はWebpack自身が追加したコードによって処理されています。また、CommonJS
ではモジュールの呼び出しが`require`という関数であるため、モジュールの切れ目はコードを書く側が意識しなければならず、うっかりすると同じモジュールが複数箇所に取り込まれる、ということになってしまいました。

これに対してViteは、ES Moduleのブラウザネイティブ対応が進んでから登場したツールで、Vite自身が取り扱うモジュール構造も出力結果もES Moduleとなっており、`import`/`export`もブラウザにある機能をそのまま使う形となっています[^1]。

そして、`import`が静的な構文ということもあり、もとのソースコードで`import`されていたファイルを別ファイルとしておく、ということも当たり前に行われて、同じコードが重複しないことを優先する形のビルド結果となります。

## 気になった問題点

そこまではいいのですが、動的な`import()`でファイルを切り分けるようにしていたプロジェクトで、「このファイルはこっちに入る」というパターンが細分化されてしまい、最小は文字列定数が1つというようなファイルを含め、100個以上のJavaScriptファイルが散らかる事態となってしまいました。

流石にここまで来ると、過不足なくコードを読み込めるメリットより、ファイル数が増えるデメリットを考えざるを得ません。

## 設定による対策

調べてみると、Viteから使うRollup側の設定に`output.experimentalMinChunkSize`というものがありました。

[ドキュメントで詳細を確認してみました](https://rollupjs.org/configuration-options/#output-experimentalminchunksize)ところ、概ね以下のような感じでした。

* 指定した容量以上になることを目指してチャンクをまとめる
* まとめた結果として、使わないコードが付いてくる形になる箇所が発生する
* 容量の基準はTree shaking後、minify前
* 副作用などを考え合わせて、マージされないこともありうる

実際に指定をかけた結果、JavaScriptチャンクは半減以下となりました。なお、動作を見ていたところ、「ふつうにチャンクを作る」→「マージできるか調べる」という流れになっていました。そして副作用があるとの判断で別チャンクになった箇所も確認できました。

[^1]: Viteの開発モードではバンドルも積極的には行わず、ソースコードの1ファイル単位で変換を行ってはブラウザで直接読み込むという構造となりますが、今回の主題はリリースビルドの方なので、そちらを掘り下げるのは割愛します。
windows11で、sketchup6 その106

# 概要
windows11に、sketchup6を入れてみた。
rubyで、3Dを書く。
練習問題やってみた。


# 練習問題
コッホ曲線を描け。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/426b54f4-f130-4530-b117-0f8638ec9773.png)

# サンプルコード

```
class Kame
	def fmod(a, b)
		x = (a / b).floor
		return a - b * x
	end
	def turn(a)
		@ANGLE = fmod(@ANGLE + a, 360.0)
	end
	def gmove(l)
		p = []
		rd = Math::PI / 180.0
		x = l * Math::cos(rd * @ANGLE)
		y = -l * Math::sin(rd * @ANGLE)
		px = @LX
		py = @LY
		p[p.length] = [px, py, 0]
		@LX += x
		@LY += y
		p[p.length] = [@LX, @LY, 0]
		p[p.length] = p[0]
		@entities.add_curve(p)
	end
	def koch(i)
		if (i <= 1)
			gmove(5)
			return
		end
		koch(i - 1)
		turn(-60)
		koch(i - 1)
		turn(120)
		koch(i - 1)
		turn(-60)
		koch(i - 1)
	end
	def initialize
		@ANGLE = 0;
		@LX = 10;
		@LY = 10;
		model = Sketchup.active_model
		@entities = model.active_entities
		koch(5)
	end
end





```

以上。
Google アナリティクスの初め方

自分のメモ用ですが参考までに

# Google アナリティクスの初め方

https://developers.google.com/analytics?hl=ja

1. 測定を開始

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3085757/abf922a8-851b-49e8-9c51-d4f822ac54ea.png)

2\. アカウントを作成

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3085757/a94efb55-d028-4d39-b3ae-7786b2c6c51a.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3085757/7c02032e-a275-4dcd-8357-3dff013ec102.png)

3\. アカウントのデータ共有設定

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3085757/0b9d52bf-6d0f-4577-8660-840682dfbcbb.png)

4\. プロパティの作成

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3085757/a1ed3e63-a45b-4c19-93eb-1a2c124c3fd3.png)

5\. ビジネスの説明

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3085757/abe8f27a-10f7-49c3-ad52-6535244b946b.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3085757/878d3d87-cde6-4290-90be-02cf42815e36.png)

6\. 規約への同意

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3085757/be24ac4d-c6bc-4ad6-a2b5-c627c4180c66.png)

7\. データ収集の開始

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3085757/b57d37fe-331b-4a47-8093-4cc2e54af507.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3085757/9e43b717-42af-4c7d-ac11-e25d601f1028.png)

8\. 「タグの設定手順を確認」から自分のwebサイトへの設定方法を確認
再帰処理(その3)

# 前回のつづき
手続きの書き方について深堀りして、合計を求める手続き sum と、積を求める手続き product について説明しました。
# 今回は？
再帰処理を使うと便利な場面、再帰する意義を考えてみましょう。その「先」に待っている「ある重要な気づき」についても触れていきます。
# リスト処理の拡張
いままでは単純なリストについてだけ考えてきました。
```
'(1 2 3 4 5 6 7)
```
このように単に要素が並んでいるだけのリストを考えました。
が、実はリストの中にもリストを含むことができ、さらにリストを含むことも出来ます。
```
'(1 (2 3) 4 ((5 6 7) 8 9))
```
このようなリストの場合に要素をすべて合計する手続きを考えたいと思います。
# 元のプログラム
リストの要素を合計する sum を再掲しておきます。
```
(define (sum items)
  (if (null? items)
      0
      (+ (car items)
         (sum (cdr items)))))
```
まずはこのて手続きにリストを要素に含むリストを引数に渡して評価してみます。
```
gosh> (sum '(1 (2 3) 4 ((5 6 7) 8 9)))
*** ERROR: operation + is not defined between ((5 6 7) 8 9) and 0
Stack Trace:
(以下省略)
```
要素にリストが現れるためエラーとなり正しく処理できません。
＋ 手続きは、リスト「((5 6 7) 8 9)」と 0 を足し算できないと言っています。
```
gosh> (+ 3 '(1 2 3))
*** ERROR: operation + is not defined between 3 and (1 2 3)
Stack Trace:
(以下省略)
```
確かに同じエラーになります。
# リストの中のリストを処理する方法
ポイントとしては、
```
・リスト内の要素がリストか否かを判断する必要があります。
・リストでないならば、今まで通り + 手続きで計算できます。
・リストならば、sum 手続きを呼び出して、リスト内の要素の合計を計算し、数値になってくれたら + 手続きで計算できます。
```
sum 手続きを修正してみましょう。リストか否かを判断するには list? 手続きを使います。
```
gosh> (list? (cons 1 (cons 2 '())))
#t
gosh> (list? (cons 1 2))
#f
gosh> (list? 2)
#f
```
ここで１つ注意して欲しいのは、(要素 . 要素) のコンスセルはリストではないので偽値を返します。
蛇足ですがコンスセルかを判断するには pair? 手続きを使います。前にリストは「(要素 . リスト) 形式のコンスセルの再帰的構造である」と説明しました。リストもコンスセルの仲間ですので pair? は真値を返します。
```
gosh> (pair? (cons 1 (cons 2 '())))
#t
gosh> (pair? (cons 1 2))
#t
gosh> (pair? 2)
#f
```
pair? と list? の真偽値の返し方の違いが理解できたでしょうか？

# sum 手続きを修正する
では実際に修正してみます。
```
(define (sum items)
  (if (null? items)
      0
      (+ (if (list? (car items))
             (sum (car items))
             (car items))
         (sum (cdr items)))))
```
ちょっと処理の見た目が複雑になってきましたが、よく見ればそんなに難しくはありません。
今までは
```
(+ 最初の要素 (sum 最初以外の要素))
```
このようになっていましたが、最初の要素がリストか否かによって処理を変えています。
```
・最初の要素がリストのとき・・・ sum 手続きに最初の要素（リストです）を与えて合計を計算してもらいます。
・最初の要素がリストでないとき・・・いままで通り＋手続きに最初の要素（リストではありません）を渡します。
```
# 実行
```
gosh> (sum '(1 (2 3) 4 ((5 6 7) 8 9)))
45
```
リストの中にリストが現れても、すべての要素を合計することが出来ました。
# 再帰的な構造を処理する
リストの中にリストが現れる構造（＝入れ子）を再帰的構造といいます。マトリョーシカも再帰的構造です。再帰処理は再帰的な構造を処理するのに適しています。特に入れ子の数が決まっていないときに威力を発揮します。マトリョーシカの人形は開けていかないと人形がいくつ出てくるかわかりませんが、再帰処理では「人形がいくつ出てくるのか」は知る必要がありません。

他の再帰構造としては、
```
・二分木などのツリー構造
・ディレクトリ階層
・json形式ファイルの解析（パース）
```
などです。さらに、
```
・Lisp プログラムコードの解析（パース)
```
も可能です。

Lisp(Scheme)言語は、プログラムコード自体の構造がリストに基づいており、書式が一貫しているため、プログラムコードさえも再帰的なリスト構造として処理することが出来ます。

このことを踏まえてもう一度 Lisp(Scheme) で書かれた手続きをよく眺めてみてください。
```
(define (sum items)
  (if (null? items)
      0
      (+ (if (list? (car items))
             (sum (car items))
             (car items))
         (sum (cdr items)))))
```
プログラムコードの中に何か構造が見えてきませんか？
そうです。Lisp(Scheme) のコードは実はリストの形式になっているのです。

Lisp(Scheme) においてはプログラムコードもリストです。そして Lisp(Scheme) はリストという構造に基づくパラダイムを処理するプログラミング言語です。つまりプログラムコードをデータとして扱うことも簡単です。これが Lisp(Scheme)言語の柔軟さであり強みです。
Agentforce Actions のエラー　アウトプットがない


+ [Agentforce error of flow running](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX00000SWBTU)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/70486aa4-7757-4a6f-9423-9450c3bf22c3.png)

:::note
Make sure this Agentforce user has the correct permissions set on the Account object. 


https://help.salesforce.com/s/articleView?id=ind.insurance_agent_permission_sets_590960.htm&type=5
:::

+ [Custom action - Order inqueries](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX00000SWIBw0AP)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/c673bbf4-ab1b-434e-bc22-e72d560dc95e.png)

別途解決策があるみたい


:::note
私も同じ問題に直面しています。これを解決するために、カスタム権限を作成し、それをエージェント ユーザーに割り当てました。 

 

権限セットには次の内容を含める必要があります。 

1. Apexクラス（必要な場合） 

2. フローを実行する 

3. プロンプトテンプレートの実行 

4. オブジェクト/フィールド/レコードタイプ 
:::
CLPFD　ヒューリスティックな工夫

# はじめに
自作のN-PrologにCLPFDを搭載しました。制約論理という考え方を理解したかったからです。自分なりに試行錯誤しできるだけ早期に枝刈りをするということを目標に基本部分を開発、搭載しました。しかし、制約論理は奥が深いのです。

# 単純な例　9queens
以下は単純な例です。9queensを解いています。

```prolog

:- use_module(clpfd).

nqueens(Queens) :-
    length(Queens, 9),       
    Queens ins 1..9,         
    all_different(Queens),   
    safe(Queens),       
    label(Queens).
    
safe([]).
safe([Q|Rest]) :-
    safe(Rest),
    no_attack(Q, Rest, 1).
    
no_attack(_, [], _).
no_attack(Q, [Q2|Rest], Dist) :-
    Q #\= Q2 + Dist,  
    Q #\= Q2 - Dist,
    Dist1 #= Dist + 1,
    no_attack(Q, Rest, Dist1).

test :- nqueens(X),fail.    

```

解を表示しないで実行時間を計測、SWI-Prologと比較すると次のようになりました。

![2025-05-17 08-00-24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33927/9e04b3ca-2691-4adb-ace7-aef31b9bbfbd.png)

![2025-05-17 08-02-02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33927/4a0ef68d-6610-46fb-866e-b5b559fdcccc.png)

SWIに比べて2倍ちょっと遅いですが、それほど悪くはありません。

# SWIに勝った！？？？
ところで次の覆面算でSWIはおもいっきり遅いのです。

```prolog
mask(Wrong,M,Right) :-
    Xs = [W, R, O, N, G, M, I, H, T],
    Xs ins 1..9,
    all_different(Xs),
    Wrong #= 10000*W + 1000*R + 100*O + 10*N + G,
    Right #= 10000*R + 1000*I + 100*G + 10*H + T,
    Wrong * M #= Right,
    label([Wrong,M,Right]).

```

![2025-05-16 16-54-11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33927/b0c1bf2f-6aa4-4ddd-aa20-bb9e7cd64ad3.png)

なんと！N-Prologの方が20倍も高速なのです？なんだそりゃ？　でも、まああのSWIを超えるというのですから
作った本人も驚きです。メジャーリーグで活躍する大谷選手の気分です。しかし・・・


# 同じ覆面算でも
よくあるsend-more-moneyの覆面算となると結果はがらりと変わります。

```prolog

send([S,E,N,D,M,O,R,Y]) :-
    Vars = [S,E,N,D,M,O,R,Y],
    Vars ins 0..9,
    all_different(Vars),
    S #\= 0,
    M #\= 0,
    1000*S + 100*E + 10*N + D + 1000*M + 100*O + 10*R + E
    #= 10000*M + 1000*O + 100*N + 10*E + Y,
    label(Vars).

```
![2025-05-17 07-35-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33927/8195bb0a-66a7-4614-9512-28e957a2818d.png)


![2025-05-17 08-09-47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33927/561be3fd-dcfb-49d7-82fa-34a4bc75fe0d.png)

SWIは桁違いに高速です。世界レベルの凄さを見た気分です。

# ヒューリスティック
どうやらSWIはヒューリスティックな手法を用いているようです。人間がsend_more_moneyの問題を人力で解くときに総当りをするはずがありません。上位の桁から推論して「こうなるはずだ！」という風にして各桁の値を求めていくはずです。SWIはそれを行っているようです。

これはなかなかおもしろい問題です。人間はいかにしたら効率よく問題を解けるのかというのをいつも模索しています。脳の計算能力はデジタルコンピューターには遥かに劣ります。しかし、それをカバーする推論能力はコンピューター以上です。面白いテーマです。いずれじっくり自分でもやってみようと思っています。

でも、今年は積みプラモデルを完成させるのでお楽しみは後回しです。

https://github.com/sasagawa888/nprolog

# 追記
変数の順番を変えるだけで劇的に高速になります。それにしてもSWIは桁違いに高速ではあるのですが。
![2025-05-18 07-59-03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33927/21009db8-697d-4203-9a85-4bf09904f94f.png)

さらに桁上がりを含めた各桁の制約式を追加すると高速化しました。
![2025-05-18 10-49-36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33927/09bbc92b-3006-4792-a1d2-17661a4b458a.png)
Spring 25 英語と日本語の内容が違う




# 英語と日本語の内容が違う？

### Lightning Experience の エンタイトルメント管理

https://trailhead.salesforce.com/ja/content/learn/modules/entitlement-management-for-lightning-experience

+ [「エンタイトルメント入門」のハンズオン Challengeが完了できない](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX00000MXT9P)


+ [レコードトリガーフローを構築するのハンズオンチャレンジ](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX00000KDbew)
+ [Please let me know if you understand：schedule task Automation Workflow](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX000000V7PF)

:::note
日本語の訳が違う？

チャレンジのURLを探せなかったのですが、言語設定を英語にしてみてください。 

おそらく以下のようになっていると思います。 
 

How to Set the Record Fields: choose the option that allows you to reference records other than the record that triggered the flow
Object: Task
Field values:
Subject = Follow up with the account owner by email (we won’t check the actual text)
Activity Date = enter today’s date (we’ll only check that you entered a date; it could be any date)

+ OwnerId = $Record > OwnerId こっちは割当先
+ WhatId = $Record > AccountId　こっちは関連先

日本語の訳が少し違うように感じます。所有者Idをセットする方には割当先を選んでください。 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/c8778add-5aa1-4c8d-b3f4-99ea95734751.png)

+ Field (項目): Related To ID (関連先 ID)、Value (値): Triggering Opportunity (トリガー商談) > Owner ID (所有者 ID) (行末に > がない所有者 ID を選択します。)
+ Field (項目): Related To ID (関連先 ID)、Value (値): Triggering Opportunity (トリガー商談) > Account ID (取引先 ID) (行末に > がない取引先 ID を選択します。)
:::

+ [Agentforce for Service設定の際、役割の入力内容について](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX000000Vtby)

Become an Agentblazer Champion 

において、Agentforce for Service設定の際、役割の入力内容について記載がなく困っております 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/12ffee36-c4d7-4a73-9dcc-c0de46478e36.png)


# 説明内容が間違っている？

+ [連絡先オブジェクトに「アカウント電話」がありません。「電話」を検索すると「勤務先電話」が表示されます。また、オブジェクト マネージャーの連絡先オブジェクトに移動しても、「勤務先電話」や「アカウント電話」が表示されません。これらに最も近いのは「電話」です。フロー内の他のすべての電話オプションに一致する連絡先オブジェクト マネージャー フィールドを見つけることができました。 ](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX000000W11T)
月3万円 OpenAI ChatGPT Codex を試して（みてる現在進行形）

# Codex を試してみた（みてる現在進行形）

> この記事は今話題のAIを使わずに書いています。オーガニック。


## OpenAIの突然の発表

OpenAIが突然12時（日本時間）でライブ配信すると言うことでめちゃくちゃ眠いのに頑張って起きていました。

https://x.com/OpenAI/status/1923212267677499469

つまり、、、これは、、、

```
こんや
12じ
エンジニアが
⚪︎ぬ
```

で、発表されたのがAIソフトウェアエンジニアリングエージェントっぽいCodexです。Codexといえば2021年くらいのGithub Copilotに使われたのがCodexだった気がしますが、

```
　　　　　　　もう、ええでしょう（ピエール瀧）
```

早速、Plusに無事ダウングレードしたChatGPTをProに戻します（通算4回目）

## 課金

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30621/a524c37d-b327-4d72-85d3-a756f3aef98c.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30621/eb02f891-7b32-43a1-a05d-9ea671206627.png)



$200です。廻らない高級寿司が食べられそうです（アトムボーイ）


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30621/20789406-eff5-479c-b766-5d9d63f914af.png)


## オンボーディングがスタート

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30621/1ea40b2a-3ec1-4f4c-be67-048c4b8f915f.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30621/dc6239f6-39b9-43b9-b3e5-ccecd594180f.png)



### CodexとGithub 連携

はい、Github使ってない人はここで終了！来世からやり直しましょう！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30621/558d3645-61f5-4e61-9f51-b85a9a603b57.png)

### お試し用に専用リポジトリをまず、Githubへ作る。

https://github.com/GOROman/OpenAI-Codex-

リポジトリを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30621/e8bf7829-2411-421f-893b-71a8f10b6a4c.png)

### 人身御供になるか？選択できます。オプトアウト。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30621/8df40958-4090-4e3b-adb2-3fbd9a2c03f6.png)

もちろんYes!高須クリニック！！！
覚悟完了！

# 全てをOpenAIへ捧げましょう！！！失うものなど何もない。

## 続き

続きはこちら↓↓↓


https://x.com/GOROman/creator-subscriptions/subscribe
Error creating agent : common.udd.object.PreSaveValidationException:



# Error creating agent : common.udd.object.PreSaveValidationException: You don't have access to bots of type InternalCopilot. More Details: ERRORS : You don't have access to bots of type InternalCopilot. WARNINGS : Topic insights__ReportingAI doesn't have org access.

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/257407f5-f1ec-44bb-8b19-18d735e43617.png)


+ [Error to create Agentforce Service Agent](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX00000SWICu0AP)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/a2014879-8679-4b9a-abda-b391b4c500ea.png)


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

+ [Hi. I'm getting this error as I hit "create" in the Trailblazer training "Error notification. Error creating agent : java.lang.IllegalArgumentException: An error occurred while checking for user with id: EinsteinServiceAgent User More Details: ERRORS : An](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX00000SWnB80AL)

+ [Getting an error message on the "Quick Start: Build a Service Agent with Agentforce - Configure Agentforce for Service](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX00000TjRNF)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/f4310683-7ccd-46cd-a8c6-76913fd3ee93.png)


:::note
When back a few steps and found I erroneously put information in the wrong field.
:::


# java.lang.IllegalArgumentException: User doesn't have access to use agent

+ [Unable to create new agent in Trailhead Playground (post Agentforce GA i.e. 10/22)](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX000000n4MC0AY)

:::note
 I figured out the answer myself.


Set. Agent's AGENT USER field = Einstein Service Agent User (auto created during TH Playground provisioning).
Setting agent user = any other user, even a system admin having DC Admin perms or "orgfarm epic" user results in error message.
:::

+ [When I click "Create" to create the Agent, I'm getting the following error message: "Error creating agent : java.lang.IllegalArgumentException: An error occurred while checking for user with id: EinsteinServiceAgent "](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX00000TkEQj)

:::note
Putting this here for anyone else that might run into this issue:

Where the instructions note to Define the settings of the agent as follows: "

EinsteinServiceAgent User"

Do NOT type in "EinsteinServie Agent User." There is a drop down box in the field, make sure you use the drop down menu and select "EinsteinServiceAgent User (coral_cloud_experience_agent.hrzjyzoop6jg@orgfarm.com) or whatever the choice is.

この問題に遭遇する可能性のある方のために、ここに記載します。

手順書には、エージェントの設定を次のように定義するように記載されています。「

EinsteinServiceAgent ユーザー」

「EinsteinServie Agent ユーザー」と入力しないでください。フィールドにドロップダウンボックスがありますので、ドロップダウンメニューから「EinsteinServiceAgent ユーザー (coral_cloud_experience_agent.hrzjyzoop6jg@orgfarm.com)」などを選択してください。
:::
【Python】sysモジュールの使い方

# Pythonで学ぶ `sys` モジュールの使い方入門

Pythonの`sys`モジュールを使うと、コマンドライン引数やシステムの状態にアクセスできます。この記事では、`sys.argv`を使って**コマンドライン引数を処理する実用例**を紹介します。

---

## ✅ 基本：`sys.argv` とは？

`sys.argv` は、Pythonスクリプトに渡された**引数のリスト**です。

```python
import sys
print(sys.argv)
````

上記スクリプトを以下のように実行すると：

```
python sample.py -m 6
```

出力は以下のようになります：

```
['sample.py', '-m', '6']
```

* `sys.argv[0]` → スクリプトのファイル名
* `sys.argv[1]` 以降 → 実際に渡された引数

---

## ✅ 実用例：引数で月を指定できるカレンダー

以下のように、`-m` オプションを使って特定の月のカレンダーを出力するスクリプトを作成できます。

```python
import datetime
import sys
from datetime import date, timedelta

args = sys.argv[1:] # 初項にファイル名が入るが不要なため[1:]とする

today = datetime.date.today()
month = today.month
year = today.year

# オプション処理
if len(args) == 0:
    pass  # 現在の年月を使う
elif len(args) == 2 and args[0] == "-m":
    if args[1].isdigit():
        month = int(args[1])
        if not (1 <= month <= 12):
            print(f"{args[1]} is neither a month number (1..12) nor a name")
            sys.exit()
    else:
        print(f"{args[1]} is neither a month number (1..12) nor a name")
        sys.exit()
else: # 適当な引数に対して
    print(f"{' '.join(args)} is neither a month number (1..12) nor a name")
    sys.exit()

# カレンダー出力
print(f"{year}年 {month}月")
print("Mo Tu We Th Fr Sa Su")

first_day = date(year, month, 1)
start_weekday = first_day.weekday()  # 0=Monday, 6=Sunday

# 月末を求める
if month == 12:
    last_day = date(year + 1, 1, 1) - timedelta(days=1)
else:
    last_day = date(year, month + 1, 1) - timedelta(days=1)

# カレンダー本体出力
day = 1
print("   " * start_weekday, end="") # スタート位置までのスペース
while day <= last_day.day:
    print(f"{day:2}", end=" ")
    start_weekday += 1
    if start_weekday == 7:
        start_weekday = 0
        print()
    day += 1
```

### 使用例

```bash
python calendar.py           # 今月のカレンダー
python calendar.py -m 6      # 6月のカレンダー
python calendar.py -m hoge   # エラー表示
```

### 引数処理のポイント

```python
args = sys.argv[1:]  # 最初の要素（スクリプト名）を除外

if len(args) == 0:
    # 引数なし → 現在の年月を使用
elif len(args) == 2 and args[0] == "-m":
    # 正しい形式 → -m のあとに数字（1〜12）が来ているかをチェック
    ...
else:
    # 異常系 → 不正なオプションや引数の数
    ...
```

---

## ✅ よくあるミス

* `sys.argv[-1]` で最後の引数だけ見てしまうと、オプションが正しく処理されません。
* 引数の数や順序をきちんとチェックしないとバグの原因になります。

---

## 📝 まとめ

* `sys.argv` を使えば、Pythonスクリプトに**インタラクティブに引数**を与えられる
* 実用的なスクリプトを通して、**条件分岐とエラーハンドリングの重要性**も理解できる

---

ぜひ自分でもカスタマイズして、コマンドラインツールの基礎を身につけましょう！
windows11で、sketchup6 その105

# 概要
windows11に、sketchup6を入れてみた。
rubyで、3Dを書く。
練習問題やってみた。

# 練習問題
リサージュ図形を描け。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/b7ba6466-9084-48e7-a45f-382172bb32d4.png)

# サンプルコード

```
def lissa2
	model = Sketchup.active_model
	entities = model.active_entities
	group = entities.add_group
	entities = group.entities
	tbeg = 0.0 if not tbeg
	tend = 6.28318531 if not tend
	stepw = 0.0062831853 if not stepw
	formula1 = "Math::sin(6 * t)" if not formula1
	formula2 = "Math::cos(5 * t)" if not formula2
	tbeg.step(tend - stepw, stepw) do |i|
		t1 = i
		t = t1
		z1 = 0
		begin
			y1 = eval(formula1)
		rescue
			y1 = 0
		end
		begin
			x1 = eval(formula2)
		rescue
			x1 = 0
		end
		y1 = 100000000 if y1 > 100000000
		y1 = -100000000 if y1 < -100000000
		x1 = 100000000 if x1 > 100000000
		x1 = -100000000 if x1 < -100000000
		t2 = i + stepw
		t = t2
		z2 = 0
		begin
			y2 = eval(formula1)
		rescue
			y2 = 0
		end
		begin
			x2 = eval(formula2)
		rescue
			x2 = 0
		end
		y2 = 100000000 if y2 > 100000000
		y2 = -100000000 if y2 < -100000000
		x2 = 100000000 if x2 > 100000000
		x2 = -100000000 if x2 < -100000000
		pt1 = [x1.m, y1.m, z1.m]
		pt2 = [x2.m, y2.m, z2.m]
		polyline2d = entities.add_line(pt1, pt2)
	end
end





```

以上。
Javaから見たDartのswitch文の相違点

# 主な違いまとめ
* すべての型に対応
* Dartはbreak;がなくてもcaseを抜ける
* パターンマッチ対応
* nullに対応

## Dartは `break;` がなくても `case` を抜ける
Javaでは`break;`がないとその後に続く`case`も逐次実行していたが（フォールスルー）
Dartでは`case`ごとに処理を終了する。
```java
String color = "red";

switch (color) {
  case "red":
    System.out.println("赤です");
  case "blue":
    System.out.println("青です");
    break;
  default:
    System.out.println("その他の色");
}
```
```text
赤です
青です
```
```dart
String color = 'red';

switch (color) {
  case 'red':
    print('赤です');
  case 'blue':
    print('青です');
  default:
    print('その他の色');
}
```
```text
赤です
```

## パターンマッチ対応
Javaでも17〜21で一部対応しているらしいが
型チェックが可能
またwhenで分岐が可能
```dart
Object value = 42;

switch (value) {
  case int n when n.isEven:
    print('偶数: $n');
  case int n:
    print('奇数: $n');
  case String s:
    print('文字列: $s');
  default:
    print('不明な型');
}
```
```text
偶数: 42
```

## nullに対応
Javaだとヌルポを投げていたが
Dartだとcase nullで対応可能
```dart
String? color = null;

switch (color) {
  case 'red':
    print('赤です');
  case null:
    print('null です');
  default:
    print('その他の色');
}
```
```text
null です
```

# おわりに
Javaで感じていた不便な部分や、直感的でない部分などがDartでは修正されていて驚きました。
また内容等に不出来がありましたらコメントください。
CopilotとGeminiで鳴子でよさこい踊りを踊る魔法少女を描いてみた。

# 概要

CopilotとGeminiで鳴子でよさこい踊りを踊る魔法少女を描いてみました。

# 実装

プロンプトと実行結果は以下の通りでした。

```
光の鳴子でよさこい踊りを踊る魔法少女を描いてください（Gemini）。
```

![光の鳴子でよさこい踊りを踊る魔法少女_20250517.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192024/806afe8b-4d56-4592-a967-6f5ce67dd228.png)



```
闇の鳴子でよさこい踊りを踊る魔法少女を描いてください（Gemini）。
```

![闇の鳴子でよさこい踊りを踊る魔法少女_20250517.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192024/a43dad27-e982-4366-af7a-3145a80ab9bc.png)



```
聖なる鳴子でよさこい踊りを踊る魔法少女を描いてください（Copilot）。
```

![聖なる鳴子でよさこい踊りを踊る魔法少女（Copilot）_20250517.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192024/8d4fe32e-096a-49ac-b35e-71450c63f937.png)

# まとめ

光の子と闇の子は可愛いかも。
何かの役に立てばと。
【エラー解消】Firebase error : failed to get document because the client is offline

## firebase emulatorとは
- Firebase
開発時にFirebaseのサービスを利用するためのプラットフォーム
- firebase emulator
Firebaseのサービスをローカルでシミュレーションしてテストを行うためのツール

## 今回の原因
firebase emulatorをコマンドプロンプトでインストールして起動していた為。

## 解決策
 connectStorageEmulator を明示的にインポートする。
```FireBase.js
import { getStorage, connectStorageEmulator } from 'firebase/storage';
import {
  getFirestore,
  getDocs,
  collection,
  connectFirestoreEmulator, // ← 忘れず追加
} from "firebase/firestore";

// 接続コード
if (window.location.hostname === "localhost") {
  console.log("🔥 Connecting to Firebase emulators...");
  connectFirestoreEmulator(db, "localhost", 8080);
  connectStorageEmulator(storage, "localhost", 9199);
}
```
コピペで簡単！SQL Server用 CREATE TABLE文ジェネレータを作ってみた

## はじめに
SQL Serverでテーブルを作成するとき、ExcelやCSVで用意した列定義を一つひとつ手入力してSQL文を組み立てるのが面倒に感じたことはありませんか？
そんな手間を解消するために、HTML＋JavaScriptだけで動作する「CREATE TABLE文ジェネレータ」を作ってみました。

できたものはこちらです。
[CREATE TABLE文ジェネレータ (SQL Server専用)](https://ken1math.github.io/sqlserver-create-table-generator/createTableGenerator.html)

## ツールの使い方
1. **テーブル名を入力**
画面上部の「テーブル名」欄に、作成したいテーブル名を入力します。

1. **列情報を貼り付け**
ExcelやCSVで用意した列情報をコピーし、タブ区切りのまま下のテキストエリアに貼り付けます。

1. **「貼り付け内容から列を追加」をクリック**
貼り付けた行ごとに列がテーブルに追加されます。

1. **必要に応じて編集**
列の追加・削除や、型・長さ、NULL許可、主キー設定は手動で変更可能です。

1. **「SQLを生成」をクリック**
CREATE TABLE文が下のテキストエリアに表示されますので、そのままコピペしてSQL Serverで実行できます。

## 注意点
- 本ツールが生成する**SQLは SQL Server専用** の構文です。他のデータベースではそのまま実行できません。

- 生成されたSQLは必ず内容をご確認のうえ、**自己責任**でご利用ください。

## おわりに
今までExcel上でやってたんですが、もっと楽になりました。
Chrome拡張機能を作ってみる

# 概要
色々作ってみた・触ってみたいシリーズ第n弾です
今回はChrome拡張機能を作ってみたいと思います

ワンタイムパスワードなどさまざまな拡張機能がありますが、実際に自分の手でも作ってさらに使うことができるようなので良い機会だと思い、触ってみました

初歩の初歩から始めるので、初心者用になります

# 拡張機能の作り方
やはりこのような開発の始めの一歩としては「Hello, World!」的なシンプルな拡張機能を作ってみようと思います

## 基本的な構成
以下のようなディレクトリ構成で拡張機能は構成されるようです

```plaintext
my-extension/
├── manifest.json(拡張機能の設定ファイル, 必須)
├── background.js(バックグラウンドスクリプト, 任意)
├── content.js(Webページに挿入するスクリプト, 任意)
├── popup.html(拡張機能のポップアップ画面, 任意)
└── popup.js(ポップアップ画面のスクリプト, 任意)
```

`manifest.json`は設定ファイルみたいなものです
actionの部分に記載したファイルなどで実際に拡張機能が何をするか決めることができます

```json:manifest.json
{
  "manifest_version": 3,
  "name": "Hello World",
  "version": "1.0",
  "description": "Popup 'Hello World!'.",
  "action": {
    "default_popup": "popup.html"
  },
  "permissions": [
    "storage"
  ]
}
```

次にpopup.html, popup.jsです
実際の動作を担当する部分です
htmlやjsで構成されるので、フロントのコードが書ける方は色々カスタムできそうですね

```html:popup.html
<!DOCTYPE html>
<html>
  <head>
    <title>Hello World</title>
  </head>
  <body>
    <h1>Hello, World!</h1>
    <button id="click-me">Click me!</button>
    <script src="popup.js"></script>
  </body>
</html>
```

```js:popup.js
document.getElementById("click-me").addEventListener("click", () => {
  alert("Button clicked!");
});
```

残りのbackground.jsとcontent.jsについてですが、今回の機能では一旦必要なさそうなのでスキップします
(概要としては、「ページの背景色を変える」や「Webリクエストの監視と制御」などができるみたいです)


# 設定手順
とりあえずこれまでに貼った3ファイルとディレクトリを作成して、拡張機能の実行してみたいと思います

1. Chromeのアドレスバーに `chrome://extensions/` を入力

1. 「デベロッパーモード」をONにする

    ![スクリーンショット 2025-05-03 10.56.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/701238/89571634-a35c-4033-bb60-8fea6b5ed097.png)

1. 「パッケージ化されていない拡張機能を読み込む」をクリック

1. 上記ファイルを保存したフォルダを選択

上記の手順が正常に完了すると以下のように拡張機能が読み込まれます

![https___qiita-image-store.s3.ap-northeast-1.amazonaws.com_0_701238_36bdad3e-b132-49f2-91d5-a4293185f919のコピー.tiff](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/701238/4c0ade9d-3539-40ba-84b8-b4627fda8b65.tiff)

## 動作確認
拡張機能の登録ができたので、実際に試してみます
拡張機能一覧から作成したHello Worldをクリックします

![スクリーンショット 2025-05-03 11.40.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/701238/af9f5402-1d2f-452f-9dff-05c410dbaa09.png)

するとhtmlが開かれるので、そこでClick me!をクリックすると、実際にpopup.jsの内容が開かれるという感じになります


![スクリーンショット 2025-05-03 11.42.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/701238/b63bd041-805e-4279-a482-65d56b27498d.png)

![スクリーンショット 2025-05-03 11.42.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/701238/9065487f-78f3-4bc4-b97a-da06ca4f6882.png)

# おわりに
今回は軽くHello Worldなるものを拡張機能で作ってみました
過去にPythonの画面操作でChrome上の操作をしていたことがありますが、Chromeを使うのであれば、自作の拡張機能を作って操作するというのが非常に向いていそうです

また何かしら作れた場合は記事にするかgithubにあげられればと思います
【公ド読】GitHub Copilot を使ってレガシ コードを最新化する

【公式ドキュメントを読もうシリーズ】GitHub Copilot を使ってレガシ コードを最新化する

## シリーズ概要

[https://qiita.com/yasu_programming/items/cec66f9e8d5d571e9ce3](https://qiita.com/yasu_programming/items/cec66f9e8d5d571e9ce3)

## URL

[https://docs.github.com/ja/copilot/using-github-copilot/guides-on-using-github-copilot/modernizing-legacy-code-with-github-copilot](https://docs.github.com/ja/copilot/using-github-copilot/guides-on-using-github-copilot/modernizing-legacy-code-with-github-copilot)

## 説明

言語の違いがあっても変換することができるみたい。
COBOLからNode.jsに変換している。

1. コードについての説明をしてもらう(`/explan`で挙動を聞いている)
2. `/workspace`でファイル間でのデータフローを図式として確認する(Mermaid記法で出力できる)
3. テストの方法を聞く
4. COBOL -> Node.jsにプロンプト入れて変換
5. 単体テスト、統合テスト

これで、言語の変更もできる模様。

## 所感

テストとか変換するためのプロンプトなど結構必要になると思われるが、確かにできるんだろうなと思った。
まだそういうケースに遭遇したことがないが、今後必要になるのかも知れない。
競プロ日記#25/05/16

# アルゴ式
[2 進数の足し算](https://algo-method.com/tasks/3145DLt5)
- 桁繰り上げの有無にcarryというboolのフラグを使い、C++ではboolがintの計算にぶち込まれたら自動で0,1扱いになることをうまく使っている
- それぞれ「着目している桁の値（0か1か）」「繰り上げがあるのかないのか」を以下の2つのbit演算のANDをもちいたif文でキレイに表現している
```
    // sum_i の 1 の位 = 答えの下から i 桁目の数字
    if (sum_i & 1) {ans += '1';}
    else {ans += '0';}

    // sum_i の 2 の位 = i+1 桁目の計算で繰り上がりの数字が登場するか
    if (sum_i & 2) {carry = true;}
    else {carry = false;}
```
こんな発想は僕にはできません。当たり前に解説ACしました。
タイトル: 2025年における生産的なPCのためのCL Debloatの利点

2025年、パソコンをより速く、効率的に使いたい人が増えています。パソコンを使っていると、起動が遅くなったり、動きが重くなったりすることがあります。これは「ブロートウェア」と呼ばれる不要なソフトが原因になることがあります。

https://cldebloat.com/ Visit now

CL Debloatは、そのような不要なソフトを取り除いてくれる便利なツールです。このツールを使うことで、パソコンのスピードが上がり、仕事や学習がもっとスムーズになります。

パソコンの起動時間を短くする方法

パソコンを使うとき、一番最初に気になるのは起動時間です。長く待つのはストレスになります。CL Debloatを使えば、不要なスタートアッププログラムを止めることができます。これにより、パソコンの電源を入れてから使えるようになるまでの時間が短くなります。

パソコンのリソースを節約する

不要なプログラムがたくさん動いていると、CPUやメモリがそれに使われてしまいます。その結果、大切な作業のスピードが遅くなります。CL Debloatは、これらのプログラムを見つけて停止させることができるため、本当に必要な作業にリソースを使えるようになります。

生産性の向上につながる

パソコンが遅いと、作業のやる気も下がってしまいます。CL Debloatによってスムーズな動作が可能になれば、集中力も高まり、仕事や学習の効率が上がります。毎日の小さな積み重ねが、大きな成果に変わるのです。

セキュリティの強化にも役立つ

ブロートウェアの中には、安全ではないものもあります。それが原因で、ウイルスや不正アクセスのリスクが高まることもあります。CL Debloatは、こうした不必要なソフトを削除することで、パソコンを安全に保つ手助けをします。

ストレージの空き容量を増やす

新しいアプリやファイルを保存しようとすると、容量が足りないことがあります。これは、使っていないソフトがたくさんインストールされているからです。CL Debloatを使えば、不要なソフトをまとめて削除できるので、空き容量が増えて、必要なものを保存できるようになります。

システムの安定性が高まる

多くの不要なソフトが動いていると、エラーやフリーズの原因になります。CL Debloatは、システムをすっきりと整理することで、こうしたトラブルを減らすことができます。安定した動作は、安心してパソコンを使える大きなポイントです。

更新とメンテナンスが楽になる

不要なソフトがあると、Windowsの更新にも時間がかかります。また、メンテナンスも複雑になります。CL Debloatを使えば、余計な更新を避け、簡単にパソコンの管理ができるようになります。

古いパソコンにも有効

CL Debloatは、新しいパソコンだけでなく、少し古い機種にも効果があります。動作が重くなってしまったパソコンでも、このツールを使えば、まだまだ活躍できるようになります。

パソコンの寿命を延ばす

パソコンに無理な負荷をかけ続けると、寿命が短くなってしまいます。CL Debloatは、負荷を軽くすることで、パソコンを長く使えるようにしてくれます。買い替えのタイミングを遅らせることができるのです。

誰でも簡単に使える

CL Debloatは、専門知識がなくても使えるように作られています。画面の指示に従うだけで、簡単に不要なソフトを削除できます。初めて使う人でも安心して使えます。

まとめ

パソコンのスピードを上げて、生産性を高めたい人にとって、CL Debloatはとても役立つツールです。起動時間を短くし、リソースを有効に使い、安全性と安定性を保ちます。古いパソコンでも使えるため、多くの人におすすめできます。
Ubuntu 24.04 で日本語入力を使う方法

## はじめに
私は、Ubuntu をインストールして、日本語入力を使いたいと思って色々と情報を調べてみたのですが、なぜかうまく入力できませんでした。一応解決はしたので備忘録として手順を書いてみました。

##  解決策

【ステップ 1】 Fcitx5 + Mozc のインストール

```
sudo apt update
sudo apt install fcitx5 fcitx5-mozc mozc-utils-gui
```
【ステップ 2】 入力メソッドに Fcitx5 を設定

```
im-config -n fcitx5
```

【ステップ 3】 再起動

以上です。


 ###  参考サイト
https://qiita.com/nouernet/items/d374ed7d1051d3d3e22e
AES-CBCとは　基本的な暗号アルゴリズム

## 目次

## 何でこんな記事を書いているのか......
どうも、初めましてRukiというネットネームで、いつもSNSを探検しています。
今回は、とあるセキュリティ問題でAES-CBCという暗号アルゴリズムが登場したため、少し語ろうと思います。

## AESとはなんぞや？
AESとは、Advanced Encryption Standardの略であり、これまでにDESというData Encryption Standardという暗号アルゴリズムがあったのですが、それの拡張版みたいなものです。
共通鍵暗号であるため、共通鍵を用います。


DESと違って、AESは

1. 鍵長が128, 192, 256ビットに拡張
2. ブロックサイズが128ビット
3. 高速で軽量（ハードウェア/ソフトウェア両方で効率的）

など色々メリットがあります。

簡単に、図にするとこうなります。

![aes.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3678270/67e08ed2-20f9-49a9-97d5-757fa35ae0dc.png)

至ってシンプルだと思います。
これにプラスして、ファイステルネットワークとかも関係しますが、今回は除外します。

## CBCって何それ？
CBCとは、Cipher Block Chainingモード(暗号ブロック連鎖モード)の略で、１つ前の暗号文ブロックと平文ブロックのXORをとってから暗号化します。

わかりにくいと思うので、図で説明します。

![cbc.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3678270/6098867e-4079-438e-ab2d-618a25ece30a.png)

CBCモードでは、基本は、１ブロック前の暗号文ブロックからXORで暗号化を行います。しかし、最初の暗号化は元となる暗号文ブロックが存在しないため、最初にランダムに生成したビット列を１ブロック分用意してから、暗号化を開始します。

## AES-CBCとは

つまりは、AES-CBCとは、共通鍵を用いた、暗号化ブロック連鎖式の共通鍵暗号方式であることがわかります。
これにより、暗号化しながら、単一の暗号・復号関係を防ぎ、尚且つ、そのまで複雑でもないことから、今でも使われている時があります。
数学1と数学2の応用数学カリキュラム



## 1. 二次関数と最適化・AI応用

### 基礎理解

二次関数は、機械学習における損失関数（2乗誤差）や最適化の基礎になります。

* 二次関数の一般形：

  $$
  y = ax^2 + bx + c
  $$

* 頂点・軸・最大・最小：

  $$
  頂点 \ x = -\frac{b}{2a}
  $$

  $$
  最大・最小値 \ y = -\frac{b^2 - 4ac}{4a}
  $$

* 平方完成の形：

  $$
  y = a(x + \frac{b}{2a})^2 - \frac{b^2 - 4ac}{4a}
  $$

### 応用・実装例

* 機械学習：最小二乗法（損失関数最小化）
* Python実装：

  ```python
  import numpy as np
  from sklearn.linear_model import LinearRegression

  x = np.array([[1], [2], [3]])
  y = np.array([2, 4, 6])
  model = LinearRegression().fit(x, y)
  print(model.coef_, model.intercept_)
  ```

---

## 2. 三平方の定理と三角比

### 基礎理解

三角形の辺の関係や、角度を計算する三角比は、距離計算や画像解析に応用されます。

* 三平方の定理：

  $$
  a^2 + b^2 = c^2
  $$

* 三角比：

  $$
  \sin\theta = \frac{\text{Opposite}}{\text{Hypotenuse}}, \quad \cos\theta = \frac{\text{Adjacent}}{\text{Hypotenuse}}, \quad \tan\theta = \frac{\text{Opposite}}{\text{Adjacent}}
  $$

### 応用・実装例

* 座標間距離計算
* 画像・信号解析

---

## 3. 三角関数とFFT（信号処理）

### 基礎理解

波形データや周期性を解析する基本技術。

* オイラーの公式：

  $$
  e^{ix} = \cos x + i \sin x
  $$

* フーリエ変換：
  信号を周波数成分に分解

* FFT（高速フーリエ変換）：計算高速化手法

### 応用・実装例

* Python実装：

  ```python
  import numpy as np
  signal = np.array([0, 1, 0, -1])
  spectrum = np.fft.fft(signal)
  print(spectrum)
  ```

---

## 4. 複素数と三相交流（工学応用）

### 基礎理解

電気工学・制御工学で重要な概念。

* 複素数：

  $$
  z = a + bi = r e^{i\theta}
  $$

* 三相交流：

  * 位相差120°
  * ベクトル表現

### 応用・実装例

* Python実装：

  ```python
  import numpy as np
  z = np.exp(1j * np.pi / 4)
  print(np.abs(z), np.angle(z))
  ```

---

## 5. 線形回帰と統計学（AI評価・解析）

### 基礎理解

回帰分析・モデル評価の基本。

* 線形回帰：

  $$
  y = ax + b
  $$

* 評価指標：

  * 平均二乗誤差（MSE）
  * 決定係数（R²）
  * 相関係数

* 統計基礎：

  * 平均・分散・標準偏差
  * 信頼区間・仮説検定

### 応用・実装例

* Python実装：

  ```python
  import statsmodels.api as sm
  x = sm.add_constant(np.array([1, 2, 3]))
  y = np.array([2, 4, 6])
  model = sm.OLS(y, x).fit()
  print(model.summary())
  ```

---

## 6. 最小情報原理と確率・積分・微分

### 基礎理解

情報理論・確率モデル・最適化基礎。

* 最小情報原理：

  * エントロピー
  * KLダイバージェンス
* 確率分布：

  * 正規分布・指数分布
* 微分・積分：

  * 勾配・累積量・確率密度

### 応用・実装例

* Python実装：

  ```python
  from scipy.stats import norm
  import sympy as sp
  x = sp.Symbol('x')
  print(sp.diff(x**2, x))  # 微分
  print(norm.pdf(0, loc=0, scale=1))  # 標準正規分布
  ```

---

このスタイルで他のテーマもまとめていきますか？
Java × Spring Boot アプリを Docker + PostgreSQL 環境で構築・デプロイする手順メモ

## 🎯 本記事の目的

Spring Boot で作成した Java Web アプリケーションを、PostgreSQL データベースと連携しながら Docker Compose で構築・起動する手順をまとめます。

以下の方におすすめです：

- Java × Spring Boot で作ったアプリを Docker で動かしてみたい
- DBにPostgreSQLを使いたい
- 開発用のローカル環境をDockerで効率よく構築したい

---

## 🐳 1. Docker & Docker Compose のインストール

### Windows（WSL2を使用）

1. [Docker Desktop](https://www.docker.com/products/docker-desktop/) をダウンロードしてインストール  
2. インストール後、設定から「WSL2 をバックエンドとして使用」を有効にする  
3. ターミナルで以下を確認：

```bash
docker -v
# Docker version 24.0.x などと表示されればOK

docker compose version
# Docker Compose version v2.x.x などと表示されればOK
```

## 📁 2. ディレクトリ構成（例）

```bash
.
├── build.gradle
├── docker-compose.yml
├── Dockerfile
├── docker-logs/
├── src/
└── build/libs/app.jar
```

## 📦 3. Dockerfile
Spring Boot アプリ（jar）をビルドして実行するための Dockerfile を用意します。
以下のコマンドでDockerfileを作成します。
```bash
nano Dockerfile
```
以下の内容がDockerfileの中身になります。
記載が終わったら、Ctrl + X → Y → Enter で保存して閉じます。
```bash
FROM amazoncorretto:21

ENV TZ=Asia/Tokyo
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

WORKDIR /app
COPY build/libs/*.jar app.jar

ENTRYPOINT ["java", "-jar", "app.jar"]
```

## 🧩 4. docker-compose.yml
アプリとデータベースを連携する構成です。
```bash
services:
  moneytrack-db:
    image: postgres:16.7
    container_name: moneytrack-db
    environment:
      POSTGRES_DB: MoneyTrack
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgresql
    volumes:
      - moneytrack-data:/var/lib/postgresql/data
    ports:
      - "5433:5432"
    networks:
      - moneytrack-network

  moneytrack-app:
    build: .
    image: moneytrack-app
    container_name: moneytrack-app
    ports:
      - "8080:8080"
    environment:
      SPRING_PROFILES_ACTIVE: docker
      SPRING_DATASOURCE_URL: jdbc:postgresql://moneytrack-db:5432/MoneyTrack
      SPRING_DATASOURCE_USERNAME: postgres
      SPRING_DATASOURCE_PASSWORD: postgresql
    volumes:
      - ./docker-logs:/app/docker-logs
    depends_on:
      - moneytrack-db
    networks:
      - moneytrack-network

volumes:
  moneytrack-data:
    name: moneytrack-data

networks:
  moneytrack-network:
    driver: bridge
```

## 🚀 5. アプリのビルドと起動
① Spring Boot アプリのビルド（Gradle）
```bash
./gradlew clean build
```
→ build/libs/ に xxx.jar が生成されます。
② Docker起動（Compose）
```bash
docker compose up -d --build
```

## 📡 6. アクセス確認
アプリ起動後、以下にアクセスして画面が表示されるか確認：
```bash
http://localhost:8080/
```

## 🧪 7. ログ確認
```bash
# コンテナログをリアルタイムで確認
docker compose logs -f moneytrack-app

# ファイルとして出力されたログを確認
cat docker-logs/application.log
```

## 🛑 8. 停止・削除
```bash
# 停止
docker compose down

# ボリュームも削除（DB初期化されます）
docker compose down -v
```

✅ 補足
`image`: を指定することで、独自イメージ名（例：moneytrack-app）を明示的に指定可能です。

`volumes`: で名前付きボリュームを指定すれば、ホスト上に保存される名前も一貫性が持てます。

🔚 おわりに
Spring Boot アプリを PostgreSQL と連携し、Docker Compose で簡単にローカル環境構築する手順をまとめました。
この構成はそのまま本番環境への移行や AWS への応用も可能です。

👨‍💻 関連リンク
Docker 公式ドキュメント
https://docs.docker.com/

Spring Boot 公式ガイド
https://spring.io/guides

PostgreSQL 公式サイト
https://www.postgresql.org/
Gemfileにあるsourceを一時的に上書きする

### 概要

Gemfileのsourceとして、下記が記載されていたとします。

```sh
source https://repo.example.com/
```

なにかしらの理由で、Gemfileでsourceは書き換えたくないけど、CIだけ変更したい場合、bundle configのmirrorを使うことで変更することが可能です。

### MIRRORS-OF-GEM-SOURCES

https://bundler.io/man/bundle-config.1.html#MIRRORS-OF-GEM-SOURCES

```
Bundler supports overriding gem sources with mirrors. This allows you to configure rubygems.org as the gem source in your Gemfile while still using your mirror to fetch gems.
```

>Bundler は gem ソースをミラーで上書きすることをサポートしています。これにより、Gemfileでrubygems.orgをgemソースとして設定しながら、ミラーを使用してgemを取得することができます。

とあるように、Gemfileの値を上書きすることが出来ます。

### コマンド

```sh
bundle config --local irror.https://repo.example.com https://repo.example.org
```
AIプロジェクトをPoCで終わらせないために

## はじめに
私はAIに関するコンサルティング/開発を行う会社を経営しています。
まだ小さい会社ですが、PoCで終わるプロジェクトは少なく、多くが本開発へと進んでいます。

PoCはその性質上100%の成功は保証されません。しかし、PoCで終わるべくして終わっているプロジェクトがその大部分を占めているように感じます。

この記事では**AIプロジェクトをPoCで終わらせない**ために考えていることをまとめました。
少しでもPoCで終わるプロジェクトが減り、意味のあるプロジェクトが増えることを祈っています。

## 記事を読んでもらいたい人
① AIプロジェクトの発注者
PoCで終わるプロジェクトを減らすには発注する人の協力が不可欠です。
盛り上がっているAI市場の中でPoCで終わるとわかりきっている提案をしてくる会社は後を断ちません(PoCだけをやっているのではという会社もあるほどです)。

② AIプロジェクトを提案する人
PoCで終わるプロジェクトは目先のお金にはなるかもしれませんが、それを繰り返すことは会社の信用を積み上げるため、健全な市場を作っていくためには得策ではないと考えます。
私はまだ勉強中の身ですが、社会にとってお客さんにとってより良い開発を増やすための一助になれば幸いです。

## PoÇで終わるかは始まる前に8割決まっている
PoCで終わるかはプロジェクトが始まる前に8割(数字は感覚ですが)決まっています。
明確なアンチパターンがPoCで終わるプロジェクトには存在します。これを踏まないだけで本開発への到達率は大きく向上します。

市場の中で見聞きしてきたアンチパターンをいくつか紹介します。
### アンチパターン① ROIの検証が不十分
このパターンが最も多い気がします。
プロジェクトを継続するにあたってROIは説明するまでもなく重要です。
しかし、成熟途中でありバズワードが行き交うAIの領域においてはROIの検証が不十分なままにプロジェクトが始まることが多いようです。

「上司がとりあえずAIを使えと言っている」「とりあえず手元にある予算で試してみよう」といったフレーズは**黄色信号**だと思います。

もちろんAIが急速に発展する中で企業として、ビジネスパーソンとしてその技術に触れ、試してみることは重要です。ただ、プロジェクトで得られる知見や人の成長もReturnとした時にどこまで会社としてInvestできるのかは事前に確認する必要があります。

端的にいうとプロジェクトに期待する利益をステークホルダーと認識を合わせ、そこに対してどこまで投資できるのかプロジェクトを始める前に確認しようということです。

当たり前のことだと思われると思いますが、驚くほどこれが十分でないプロジェクトが存在します。

### アンチパターン② 絶対にできないことを夢見ている
このパターンも割と耳にします。
コンサルからの提案を信じてしまい、絶対に得られないReturnを夢見て多額の投資をしてしまうパターンです。

AIのできることが急激に広がる中でその最先端をキャッチアップすることが難しく、過大な期待が市場に広がっていることが原因です。

まだ**最先端の研究者たちが実現できていないこと**をインテグレーションを主な生業とするベンダーに数億円かけて依頼したところでまず間違いなく期待通りのものは出来上がりません。

社内に有識者がいない場合、このアンチパターンを避けるためには提案のステークホルダーではない専門家の力を借りる必要があります。私もたまにですがこの第三者として提案の評価を依頼されることがあります。

### アンチパターン③ 最終像が一致していない
技術者(ベンダー)とビジネスサイドの持っている最終像が一致していないことによりプロジェクトがうまくいかないパターンです。
技術者側が暗黙の了解として知っている限界がビジネスサイドに伝わっていないことで起こります。
**文章などで最終像に合意していてもそこから想像している最終像が一致しているとは限りません。**

具体的な画面イメージや想定される達成割合、できること、できないことを書き出して認識をできる限り揃える必要があります。

大手の企業でもこのような事例が散見されます。

## プロジェクトが始まってからの落とし穴
プロジェクトが始まったあとにも落とし穴があります。
いくつかあると思いますが、今回はその中でも大きな落とし穴である **「作ってみたけど現場に導入されない」** を紹介したいと思います。

ROIも検証して実際に想定していたものができたのに現場に導入されないということが割とあるようです。

主な原因は下記です(MECEではありませんが)。

- 現場はそもそも困っていない
- 現場の賛同が得られていない
- クオリティが実用レベルに至っていない

これも書いてみると当たり前です。

ではこのような事態を避けるためにはどうすれば良いのか。
最も重要なことは**プロジェクトの早い段階で現場を巻き込むこと**です。そして技術者を含むプロジェクトメンバーが深く現場を理解することから始める必要があります。

大企業になればなるほど事業部と技術部の距離が離れてしまい、これは言うほど簡単なことではありませんが、プロジェクトを意味あるものにするためには必須だと思います。

プロジェクトが始まる時にはまず現場を訪れ、時間をかけてそこで働く人や業務を理解することに重きを置いています。これはとても泥臭い作業ですが**理論上いいもの**ではなく**実際に使われるもの**を作るためには必要なプロセスだと考えています。

## 最後に
いくつかのPoCで終わるAIプロジェクトのアンチパターンを紹介しました。
もちろんこれに尽くされませんが少しでもPoCの成功確率をあげる一助になれば幸いです。