OmniAICreator/Qiita-1.07M huggingface dataset:
【初心者向け】OSS開発のはじめかた


これからOSS開発を始める方向けにコマンドやエラーハンドリングの記録を掲載しています。


##### この記事でわかること
- `good first issue` で見つけたOSSにコントリビュートする方法  
- `fork → clone → commit`までの流れ  

---

### 目次
1. リポジトリのクローンとセットアップ
2. 仮想環境の作成とセットアップ
3. 変更のコミットとプッシュ
4. エラーハンドリング
5. 作業メモ

---

```bash
① リポジトリのクローンとセットアップ

1. Fork後、ローカルにClone
$ git clone https://github.com/***/Bowler.git
$ cd Bowler
$ pwd

# 出力例: /***/***/Bowler

2. upstream にオリジナルのリポジトリを登録（任意）
$ git branch 

# 出力例: * main

$ git remote add upstream https://github.com/facebookincubator/Bowler.git
$ git remote -v

# 出力例:
# origin  https://github.com/***/Bowler.git (fetch)
# origin  https://github.com/***/Bowler.git (push)
# upstream https://github.com/facebookincubator/Bowler.git (fetch)
# upstream https://github.com/facebookincubator/Bowler.git (push)

3. 最新の状態を取得
$ git checkout main
$ git pull upstream main
$ git push origin main  # フォークしたリモートリポジトリにも反映

4. 仮想環境を作成せずに始める場合（推奨）
$ make dev


② 仮想環境の作成とセットアップ（Pythonの場合）

1. 仮想環境の作成＆有効化

$ python3 -m venv .venv
$ source .venv/bin/activate  # 仮想環境の有効化
# deactivate  # 仮想環境の無効化

2. 必要なセットアップ

$ make setup 
$ python setup.py develop


③ 変更のコミットとプッシュ

1. 動作確認

$ pip list | grep bowler
# 出力例: bowler 0.1.dev186+g92c9eeb.d20250228 /***/***/Bowler

$ make test  # テストの実行
$ python -m coverage report  # テストカバレッジの確認
$ make format  # コードの自動整形

2. 変更をコミット

$ git add .
$ git commit -m "Apply code formatting using isort and black"

④ エラーハンドリング
1. codecov==2.1.9 のバージョンエラー

# エラーメッセージ:
# ERROR: Could not find a version that satisfies the requirement codecov==2.1.9 (from versions: 2.1.13)
# ERROR: No matching distribution found for codecov==2.1.9

$ python -m pip install --upgrade pip
$ python -m pip install codecov --no-cache-dir
$ nano requirements-dev.txt  # 必要に応じてバージョン変更

2. setuptools のバージョンエラー

# エラーメッセージ:
# ERROR: setuptools==58.0.4 is used in combination with setuptools-scm>=8.x
# setuptools-scm requires setuptools>=61

$ python -m pip install --upgrade setuptools

3. click の ImportError
# エラーメッセージ:
# ImportError: cannot import name '_unicodefun' from 'click'

pip install --upgrade black
pip install --upgrade click

⑤ 作業メモ

1. upstream について
git pull upstream main のように使うときに必要。
git remote -v でリモートリポジトリの名前を確認すると、remote add で設定したURLリポジトリが upstream として表示される。
ちなみに、自分のリポジトリは origin

2. 仮想環境について
プロジェクトごとに独立した環境を作るときに必要。
環境を分けずに複数のPythonプロジェクトを同じ環境で開発すると、パッケージのバージョン衝突が発生しやすい。
予期せぬエラーや互換性の問題を避けるために、必ず仮想環境を作成することを推奨。

まとめ
この記事では、OSSにコントリビュートするための 基本的なコマンド操作 や エラーハンドリング についてまとめました。
実際に good first issue から始めて、 fork → clone → commit までの流れをスムーズに進められるようになることが目標です。

次のステップとして、Pull Request（PR） の作成方法やレビューの受け方 についてもまとめる予定です！
AWS WAF(Web Application Firewall)

## AWS WAF(Web Application Firewall)
Amazonが提供するクラウド型のWebアプリケーションファイアウォールサービス。
脆弱性を突いた外部からの攻撃や不正アクセスから、Webアプリケーションを保護します。ウェブサイトに悪意のあるデータを送り込むことで情報を盗み出す「SQLインジェクション」や、ユーザーになりすまして不正な操作を行う「クロスサイトスクリプティング」などを防御します。
AWS WAFは、Amazon CloudFront、Application Load Balancer、Amazon API Gatewayなどに割り当てて利用します。
## Web ACL(Web Access Control List)
AWS WAFの機能の1つで、Webアプリケーションのアクセス制御を行うために使用されるリソース。
訪問者のIPアドレスや、ウェブページへのリクエスト内容（例：HTTPヘッダー、HTTP本文、ウェブページのアドレスなど）に基づいて、どのようなアクセスを許可し、どのようなアクセスを遮断するかを細かく決めることができます。
- Webアプリケーションの脆弱性や攻撃から保護する
- Webアプリケーションの通信をフィルター、監視、ブロックする
- Webアプリケーションに対する要求処理順序を定義する
- 地理的一致ルールやレートベースルールなどがある
## AWS Shieldとの違い
AWS WAFとAWS ShieldはどちらもAWSが提供しているセキュリティサービスですが、守備範囲と防御できる攻撃が異なります。AWS Shieldは、DDoS攻撃からの保護に特化したサービスです。
Microsoft Defender for Endpoint デバイスを Intune に登録する - オンボードする

## Microsoft Defender Portal

https://learn.microsoft.com/ja-jp/defender-business/mdb-get-started

## Defender for Endpoint と Intune を接続する

Microsoft Defender for Endpoint を Intune に接続し、Defender for Endpoint のデバイスをオンボードする。

https://learn.microsoft.com/ja-jp/mem/intune/protect/advanced-threat-protection-configure


## Windows 10/11 デバイスを Intune に登録する

登録するためのデバイスを VM か何かで用意しておく。

https://learn.microsoft.com/ja-jp/mem/intune/user-help/enroll-windows-10-device


## Intune 管理センター

https://intune.microsoft.com/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93824/3b5dbb51-fbf0-47ba-901e-0cdc1a3383b9.png)



## オンボード

登録したデバイス上でここで手に入るスクリプトを実行する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93824/282fbc58-5135-456c-aca8-c9ef366800e3.png)


## Microsoft Defender ATP コネクタ

https://learn.microsoft.com/ja-jp/connectors/wdatp/

コネクタを使ってデバイスの情報が取れる。


## Defender for Endpoint API

https://learn.microsoft.com/ja-jp/defender-endpoint/api/exposed-apis-create-app-webapp

https://learn.microsoft.com/ja-jp/defender-endpoint/api/apis-intro

https://learn.microsoft.com/ja-jp/defender-endpoint/api/get-machines
PlaywrightでChrome拡張機能のテストをする時にやること

Playwrihtでは以下のようにChrome拡張機能のテストを行うことができます。


```js
const { chromium } = require('playwright');

(async () => {
  const pathToExtension = require('path').join(__dirname, 'my-extension');
  const userDataDir = '/tmp/test-user-data-dir';
  const browserContext = await chromium.launchPersistentContext(userDataDir, {
    channel: 'chromium',
    args: [
      `--disable-extensions-except=${pathToExtension}`,
      `--load-extension=${pathToExtension}`
    ]
  });
  let [backgroundPage] = browserContext.backgroundPages();
  if (!backgroundPage)
    backgroundPage = await browserContext.waitForEvent('backgroundpage');

  // ここにやりたいことを書く

  await browserContext.close();
})();
```

ですがChrome ウェブストアにてリリースされた拡張機能をテストするにはこれとは少し違います。
２つの手段があると思います。


## 方法１:crxファイルを入手しフォルダーに解凍し、前述のテストをする

Chrome拡張機能に使われているcrxファイルは中身はただのzipファイルです。
どうにかして入手できれば解凍し配置することで前述のテストができます。

この記事にはダウンロードできるみたいな話ですが、実際は空のレスポンスが返ってくるだけでした。（誰か知っていたら教えてください）

```bash
curl -LO https://clients2.google.com/service/update2/crx?response=redirect&prodversion=[PRODVERSION]&acceptformat=crx2,crx3&x=id%3D[EXTENSIONID]%26uc
```

https://stackoverflow.com/questions/7184793/how-to-download-a-crx-file-from-the-chrome-web-store-for-a-given-id

## 方法２：chrome拡張機能をインストールしたユーザーデータを作成し、そのユーザーデータを使ってテストをする

普段はPlaywrightのcodegenを使い、テストコードの生成を行っております。
そこにひと工夫入れることで、ユーザーデータの作成と、テストコードの実行を同時にすることができました。
具体的には以下のコードです。

```js
const { chromium } = require('@playwright/test');

(async () => {
  const browser = await chromium.launch({
    headless: false,
    ignoreDefaultArgs: ['--disable-extensions'],
  });

  const userDataDir = './data';
  const context = await chromium.launchPersistentContext(userDataDir, {
    headless: false,
    channel: 'chromium',
  });

  await context.route('**/*', route => route.continue());

  const page = await context.newPage();
  await page.goto('https://chromewebstore.google.com/');

  // ここでChrome拡張機能のインストールをする
  await page.pause();
  // インストールができたらレコードボタンを押してコード生成
})();
```

デフォルトではPlaywrightはChromeに`--disable-extensions`を渡すので、Chrome拡張をインストールできません。ignoreDefaultArgsに渡すことで拡張機能無効化を無効化します。

参考：
https://github.com/microsoft/playwright/blob/main/packages/playwright-core/src/server/chromium/chromiumSwitches.ts#L70

後はユーザーデータを使用していつもの如くテストを実行するだけです。

```js
  const userDataDir = './data';
  const context = await chromium.launchPersistentContext(userDataDir,{
  ...

```


## まとめ

Chrome拡張機能に関する記事はなかなかありませんが、Playwrightはそういったところまでカバーできます。
今後も使い続けたいですね。
【Chrome拡張】グロ画像を見たくない！【検索してはいけない言葉】


検索してはいけない言葉を調べたい！
でもグロ画像は見たくない！って思う方へ。

そんなときは画像にぼかしをかけましょう。

## ステップ1

ScriptAutoRunnerをChrome拡張機能に追加してください。
これは任意のJavaScriptを自動で実行するChrome拡張機能です。

https://chromewebstore.google.com/detail/scriptautorunner/gpgjofmpmjjopcogjgdldidobhmjmdbm

## ステップ2

以下のコードをScriptAutoRunnerに追加してください。

```js:spoiler.jsの読み込み
// https://github.com/joshbuddy/spoiler-alert/blob/master/spoiler.min.js
(function(){if(typeof Object.assign!="function"){(function(){Object.assign=function(target){"use strict";if(target===undefined||target===null){throw new TypeError("Cannot convert undefined or null to object")}var output=Object(target);for(var index=1;index<arguments.length;index++){var source=arguments[index];if(source!==undefined&&source!==null){for(var nextKey in source){if(source.hasOwnProperty(nextKey)){output[nextKey]=source[nextKey]}}}}return output}})()}window.spoilerAlert=function(selector,opts){var elements=document.querySelectorAll(selector);var defaults={max:4,partial:2,hintText:"Click to reveal completely"};opts=Object.assign(defaults,opts||{});var maxBlur=opts.max;var partialBlur=opts.partial;var hintText=opts.hintText;var processElement=function(index){var el=elements[index];el["data-spoiler-state"]="shrouded";el.style.webkitTransition="-webkit-filter 250ms";el.style.transition="filter 250ms";var applyBlur=function(radius){el.style.filter="blur("+radius+"px)";el.style.webkitFilter="blur("+radius+"px)"};applyBlur(maxBlur);el.addEventListener("mouseover",function(e){el.style.pointer="Cursor";el.title=hintText;if(el["data-spoiler-state"]==="shrouded")applyBlur(partialBlur)});el.addEventListener("mouseout",function(e){el.title=hintText;if(el["data-spoiler-state"]==="shrouded")applyBlur(maxBlur)});el.addEventListener("click",function(e){switch(el["data-spoiler-state"]){case"shrouded":el["data-spoiler-state"]="revealed";el.title="";el.style.cursor="auto";applyBlur(0);break;default:el["data-spoiler-state"]="shrouded";el.title=hintText;el.style.cursor="pointer";applyBlur(maxBlur)}})};for(var i=0;i!==elements.length;i++)processElement(i)}})();
```

```js:画像をぼかす
spoilerAlert("img, video", {
    max: 30, // ぼかしレベル
    partial: 30, // マウスオーバー時のぼかしレベル
});
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649673/832c2da6-0870-48d1-8093-cf7d7943177e.png)


## ステップ3

はい、するとページを開いたときに画像にぼかしが入ります。
やったー！

:::note warn
画像をクリックすると解除されます。
:::

:::note warn
ScriptAutoRunnerの処理が終わるまで目をつぶっていてください。
:::

:::note warn
spoilerAlert関数の第1引数で指定したタグ以外で画像を表示された場合は泣きましょう。
:::

## 参考

https://github.com/joshbuddy/spoiler-alert

https://syncer.jp/how-to-applying-a-blur-to-image-and-text-by-javascript
Web AIエージェントの脆弱性を徹底分析：スタンドアロンLLMとの比較と対策

# Web AIエージェントはなぜスタンドアロンのLLMよりも脆弱なのか？― セキュリティ分析 ―

今回は、最新の研究成果である「**Why Are Web AI Agents More Vulnerable Than Standalone LLMs? A Security Analysis**」という論文をご紹介します。本研究では、Web AIエージェントがスタンドアロンの大規模言語モデル（LLM）と比較して、**なぜより高いセキュリティ上の脆弱性を持つのか**を詳細に分析し、その原因と対策を提案しています。

---

## 論文情報
- **タイトル**: Why Are Web AI Agents More Vulnerable Than Standalone LLMs? A Security Analysis  
- **リンク**: [https://vulnerable-ai-agents.github.io](https://vulnerable-ai-agents.github.io)  
- **発表日**: 2025年2月28日  
- **著者**: Jeffrey Yang Fan Chiang, Seungjae Lee, Jia-Bin Huang, Furong Huang, Yizheng Chen  
- **DOI**: 未提供  

---

## 背景と目的

### **Web AIエージェントの普及と新たな脅威**
近年、LLMを活用したWeb AIエージェントが急速に普及しています。これらのエージェントは、Webブラウザを介して情報検索、フォーム入力、ショッピング、予約などの複雑なタスクを自動で遂行できるため、幅広い分野で利用が拡大しています。

しかし、その利便性とは裏腹に、Web AIエージェントは**スタンドアロンLLMよりも著しく高いセキュリティリスク**を抱えています。特に、以下のような攻撃に対して脆弱であることが問題視されています：

- **フィッシング攻撃**：悪意のあるメールの自動作成・送信
- **マルウェア拡散**：Web操作を通じた悪意のあるスクリプトの実行
- **情報漏洩**：意図せず機密情報を開示するリスク
- **クリック詐欺**：広告詐欺の実行や不正アクセスの補助

### **本研究の目的**
本研究では、Web AIエージェントがなぜこのようなセキュリティリスクを抱えているのかを徹底的に分析し、以下の3つの視点からその原因を特定しました。

---

## 研究の焦点：Web AIエージェントの脆弱性を生む3つの要因

本研究では、Web AIエージェントが**スタンドアロンLLMと比べて46.6%も高い確率で悪意のある要求を受け入れる**ことを実験的に確認しました。その主な要因は以下の3つに分類できます。

### **1. ユーザー目標のシステムプロンプトへの埋め込み**
- Web AIエージェントは、ユーザーの要求をシステムプロンプトに直接組み込むことで、意図せず有害な命令を受け入れるリスクが高まる。
- 例えば、ある攻撃者が「フィッシングメールを作成せよ」と入力した場合、エージェントはその指示を「目標」として認識し、システム全体がその達成に向かって動いてしまう。

### **2. マルチステップアクションの生成**
- Web AIエージェントは、単発の応答ではなく**複数のステップを経て目標を達成する**ため、危険な命令が少しずつ進行しやすい。
- たとえば、メール送信タスクで「宛先の入力 → メール本文の作成 → 送信ボタンのクリック」という**分割された処理**を行うため、エージェントは途中でリスクを認識しにくくなる。

### **3. 観察と履歴データの利用**
- 過去のアクションや環境の変化を考慮しながら動作するため、安全でない決定が蓄積されやすい。
- これにより、たとえ最初に「危険」と判断していた命令であっても、次第に許容する方向へ変化する可能性がある。

---

## 実験の概要と結果

### **1. ファイングレインド評価による詳細分析**
従来のLLM脆弱性評価は「成功/失敗」の二元評価が一般的でしたが、本研究ではより詳細な**5段階の危険度評価手法**を導入しました。

| レベル | 説明 |
|-------|----------------|
| **Clear Denial（明確な拒否）** | 完全に拒否し、危険な命令を実行しない |
| **Soft Denial（部分的拒否）** | 途中まで拒否するが、一部のアクションを実行する |
| **Non-Denial（非拒否）** | 一切拒否せず、命令をそのまま実行する |
| **Harmful Plans（有害計画）** | 有害な計画を立案するが、最終的な実行はしない |
| **Harmful Actions（有害アクション）** | 有害な行動を完全に実行する |

### **2. 各コンポーネントの影響評価**
本研究では、Web AIエージェントのどの部分が特に脆弱性を引き起こしているかを詳細に分析しました。

| コンポーネント | Clear Denialの低下率 |
|--------------|------------------|
| **システムプロンプト内のユーザー目標** | -6.7% |
| **マルチステップアクション生成** | -20% |
| **イベントストリーム（履歴の考慮）** | -20% |
| **モックアップWeb環境から実際のWeb環境へ** | -43.3% |

---

## まとめと今後の課題

本研究は、Web AIエージェントがスタンドアロンLLMよりも**はるかに脆弱であることを明確に示し**、その原因となる要因を特定しました。特に、システムプロンプトの扱い方やエージェントのマルチステップ処理の設計が、安全性に大きく影響を与えることが明らかになりました。

### **今後の課題**
- **より現実的な評価環境の構築**（モックアップ環境と実Web環境の差異を縮小）
- **ユーザー目標の安全な処理方法の開発**
- **リアルタイムな安全フィルタリング技術の強化**
- **動的なリスク評価アルゴリズムの導入**
- **自己修正可能なAIセキュリティモデルの開発**

本研究の成果は、今後のAIエージェントの設計とセキュリティ向上において、重要な指針となるでしょう。

この記事が、皆さんの研究や実務に役立つことを願っています。ご質問やフィードバックがありましたら、コメント欄にお寄せください。
オンラインで画像にモザイク加工ができるモザイクディター

![Monosnap Webモザイクエディタ - モザイク加工に特化したシンプルなオンライン画像エディタ 2025-03-01 15-42-03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421986/61b88acc-9794-43a9-a7d7-77851f9cff27.png)

ブラウザのみで画像にモザイク加工をかけられるツールを作りました。
手軽にモザイク加工をかけたいとお考えの皆さん、必見です！
今回作成した「モザイクエディタ」は、モザイク編集のみに特化したツールで、オンライン上で簡単に画像編集ができるツールです。

https://mosaic.sukerou.com/


## 生成AI（ChatGPT）恐るべし

このツールはChatGPTでほぼ全て作りました。
内部はReactで作られています。
なんと開発時間は１０分程度です...
その後、デザインの調整やサイトを公開するための作業は発生していますが、恐るべき開発能力です。


## 何ができるの？

今回公開した「モザイクエディタ」は、モザイク加工に特化したシンプルな画像加工ツールです。
画像をアップロードして、モザイクをかけたい範囲をマウスで選択すると、その部分をモザイク加工できます。

![m02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421986/859ba3ae-1797-4836-a731-57d5332bdab5.png)


ブログなどに画像を掲載する際、個人情報を隠すのに便利です。

よかったら使ってみてください。
【26卒】文系学生が年内に就職活動を終えるまで

## はじめに

文系学生が年内に内々定をもらって就職活動を終えるまでにやったことをまとめます。気が向いたときに書いているためまだまだ未完成です。ご理解いただければと思います。

## 対象者
- **理系学部（情報系）でこれから就職活動を始める方**
  会社の規模ごとの選考のレベル感や必要な準備について知りたい方は[こちら](https://qiita.com/takutosan/private/250465338a57118c525e)
<r>

- **理系学部（情報系以外）および文系学部からエンジニアを目指す方**
  プログラミング自体の経験はあるが、エンジニア職に進むべきか迷っている方は[こちら](https://qiita.com/takutosan/private/b8b8f1ca80ed42833c20)
<r>

- **本選考および早期選考を受けている方**
  会社の規模感としては、中堅企業～メガベンチャーまたはスタートアップを受けている方は[こちら](https://qiita.com/takutosan/private/5773847601ffcedefaae)

> **補足**  
> ここでいう **中堅企業、スタートアップ企業** とは、特定の領域・プロダクトでトップシェアを獲得している企業を想定しています。  
> （例: アンドパッド、BuySell Technologies、セーフィー など）

---

## 目次（予定）
1. **就活のスケジュールと戦略**
   - いつから始めるべきか？
   - 早期選考と本選考の違い
   - 企業の選び方と業界研究の進め方 
   <br>

2. **プログラミング学習とポートフォリオ**
   - AtCoder Bランクの問題を解く習慣
   - ポートフォリオサイトの作成と技術選定
   - チーム開発の経験を積む（インターン・ハッカソン）
   <br>

3. **インターンシップと実務経験**
   - 長期インターンで学んだこと
   - 企業ごとのインターン選考の特徴
   - スクラム開発・Git運用の実践
   <br>

4. **選考対策（コーディングテスト・面接）**
   - コーディング試験の対策方法
   - 面接で聞かれた質問と回答のポイント
   - 技術選考・カルチャーマッチの違い
   <br>

5. **内々定後の振り返り**
   - 就活を通じて学んだこと
   - これからのキャリアプラン
   - 企業選びで重視したポイント

---

参考

https://qiita.com/reeen/items/2494fffc4dece27e0bcc
画面キャプチャをCanvasで表示させる方法


## サンプル

ほぼChatGPTが書きました。
キャプチャ元のブラウザサイズが変化しても問題ナッシングです。

```html:index.html
<!DOCTYPE html>
<html lang="ja">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>WebRTC + Canvas</title>
  <style>
    canvas {
      border: 1px solid black;
      width: 100%;
      max-width: 640px;
    }
  </style>
</head>

<body>
  <button id="startCapture">画面キャプチャ開始</button><br>
  <video id="video" autoplay playsinline style="display: none;"></video>
  <canvas id="canvas"></canvas>

  <script src="main.js"></script>
</body>

</html>
```

```javascript:main.js
const startButton = document.getElementById('startCapture');
const video = document.getElementById('video');
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');

let animationFrameId = 0;

async function startCapture() {
    try {
        cancelAnimationFrame(animationFrameId);

        const stream = await navigator.mediaDevices.getDisplayMedia();
        video.srcObject = stream;

        video.onloadedmetadata = () => {
            video.play();
            drawToCanvas();
        };
    } catch (err) {
        console.error("画面キャプチャエラー:", err);
    }
}

function drawToCanvas() {
    // video のサイズが変わっていたら canvas を更新
    if (canvas.width !== video.videoWidth || canvas.height !== video.videoHeight) {
        canvas.width = video.videoWidth;
        canvas.height = video.videoHeight;
    }

    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.drawImage(video, 0, 0, canvas.width, canvas.height);

    animationFrameId = requestAnimationFrame(drawToCanvas);
}

startButton.addEventListener('click', startCapture);
```
【長期インターン】料金計算APIの実装

## はじめに
2024 年 6 月から大阪のベンチャー企業で週 1〜2 回ペースの長期インターンに参加し、**デマンド交通システム**のバックエンド開発を担当しました。  
既存システムではフロントエンドの JavaScript で料金を計算していましたが、サーバー側で処理をできるようにし、他のシステムからも利用できるようにするため、**料金計算 API** の PHP 版を実装しました。

##### デマンド交通システム

https://metaism.co.jp/service_smart-demand-transportation

---

## 料金計算 API について

#### 機能概要
緯度・経度を受け取り、走行距離と利用者属性に応じて料金を返す REST API です。呼び出し元は以下の 2 つ。

1. Web 予約画面 ― ユーザー向け  
2. 管理者画面 ― 管理画面向け  

自治体ごとに適応される割引条件が異なり、障害の有無とその種別、未就学児、幼児など条件を満たす利用者には割引が適応される。
今回の案件では以下の割引条件を考慮する必要があった。

* 幼児（3歳児未満）は無料
* 未就学児（3歳以上5歳以下）は300引き
* 利用者本人が障害を持つ場合、300引き
* 利用者本人が重度障害区分の場合、同乗者1名のみ300引き

なお、もし「未就学児」で「障害を持つ」利用者が配車予約した場合には、600円引きとならないよう、最大300円引きまで適応されるようにした。（割引組み合わせ管理）

####  `api_get_feeクラス`

主なメソッド
|  | 機能 | 説明 | メソッド |
|---|------|------|---------------------------------------------|
| 1 | エリア判定 | 緯度経度からエリア ID を取得 | `get_area_by_id()` |
| 2 | 基本料金算出 | 料金マスタを参照し、エリア ID から基本料金を取得。| `get_default_fee()` |
| 3 | 予約者割引判定 | ユーザーIDから、障害者・未就学児・高齢者などの割引適用可否を取得 | `check_discount_adaptive()` |
| 4 | 料金計算 | 基本料金に割引を適用し金額を算出 | `calc_fee()` |
| 5 | 同乗者料金計算 | 同乗者がいる場合は、同乗者の属性を確認し料金を算出 | `calc_fellows_fee()` |


#### 主なデータテーブル

| テーブル        | 用途                     | 主なカラム                                  |
|-----------------|--------------------------|---------------------------------------------|
| `customers`     | 顧客属性                 | `id`, `age`, `disable`               |
| `fee`   | 基本料金 | `area_id`, `from_lon`, `from_lat`, `to_lon`, `to_lat`,`default_fee` |
| `discount`     | 割引管理               | `discount_id`           |
| `discount_combo`     | 割引組み合わせ管理                | `discount_combo_id`              |

---

## 使用した技術
- 言語: PHP
- フレームワーク: Laravel（たぶん） 
- DB: PostgreSQL
- バージョン管理: Git 

---

## できるようになったこと
- オブジェクト指向でコードを書けるようになった。
    - これまで用語としては知っていたけど、実際に意識して書いたことはなかった。
    - 実務ではほぼ全てオブジェクト指向で書かれており、理解していないと結構苦労するなと思った。
- GitHubの使い方を学んだ。
    - これが意外と大きな成長。
    - 最新の状態を取得し自分の変更をpushするまでの一連の流れを抑えた
    - 実務ではrelease, develop, featureブランチと3つに分けていることを知った。
- Chromeの検証機能（DevTools） の使い方を学んだ。
    - 「ネットワーク」を見て、リクエストがどこに送られているか、レスポンスはどうなっているか確認できることを知った。
    - console.logしたログの確認の仕方を学んだ
- 社員の方にコードレビューをしてもらって、誰が見てもわかるコードの重要性を知った
    - 個人開発では「動けばいい」と思いがちだけど、実務では保守性や可読性、バグに繋がらないかどうかが重視される。
    - 特に変数名のわかりづらさ、不要な分岐処理、渡ってきたデータのバリデーションチェックなどが指摘された。
    - プロのエンジニアの方にレビューしていただけるのは非常に貴重な経験。

---

## 苦労したこと

| 課題                               | 苦労したこと                               |
|------------------------------------|--------------------------------------------------------------------|
| オペレーター画面と Web 予約画面でレスポンス形式が異なる | 片方は配列、もう片方は文字列を必要とし、キー名もバラバラだった。<br> どちらの画面でも使えるように、必要な形式をすべて含んだレスポンスを API 側で構成して返すようにした。 |
| オペレーター画面からAPI叩いても料金計算が動かない                     | APIリクエスト先を切り替えるswich文でbreakを書き忘れていたため、APIがレスポンスを返せていなかった。<br> 気づくまでに時間がかかった。 |
| 履歴から特定の地名を選ぶと、別の地名が表示される | 住所は同じでも地名が異なる候補が存在したため、JavaScript 側の一致判定を修正する必要があった。<br> 緯度経度が一致するかどうかで判定し、正しく一致する地名だけを選ぶようにコードを修正した。 |
データ型の基本 まとめ

# はじめに
プログラミングにおいてデータ型の選択は重要です。
どのような場面でどんなデータ型を選択するかでプログラムの挙動が変わってしまうこともあるため、使用する主なデータ型を整理しました。

# データ型が重要な理由
データ型は、正確性・効率性・可読性・保守性・互換性の観点から重要です。
例えば、正確性について、データ型が、変数や値がどのような種類のデータを扱うかを明確にすることによって、型不一致によるエラーの防止やデータの整合性の保証を行なうことができます。<br>
また、メモリの使用量を最適化するためにも重要です。異なるデータ型は、メモリ内で異なるサイズを占めます。
例えば、整数型（int）は通常、4バイトまたは8バイトを占めますが、文字型（char）は通常、1バイトを占めると言った具合です。

## データ型の種類
データ型には大きく、「プリミティブ型」と「参照（オブジェクト）型」が存在します。

### プリミティブ型
最も基本的なデータ型で、単一の値を直接的に表現するために使用されます。

#### 主な特徴
1. 単一の値
・プリミティブ型は、1つの値だけを保持
2. メモリ効率
・メモリ上で直接的に値が格納されるため、処理が高速
・メモリサイズが固定されている
3. 不変性
・多くの言語で、プリミティブ型の値は変更できない（イミュータブル）
4. 使用メモリ
・スタックメモリを使用するのが一般的
・値そのものをスタックメモリに格納する
5. データの変更
・値をコピーして使用するため、元の値に影響を与えない（値渡し）

### プリミティブ型一覧

|データ型|用途|例（言語）|
|-|-|-|
|整数型|整数を表現|`int` (Java)<br>`number` (JavaScript)|
|浮動小数点数型|小数を含む数値を表現|`float` (Java)<br>`number` (JavaScript)|
|文字型|単一の文字を表現|`char` (Java)|
|真偽値型|真偽値を表現|`boolean` (Java)<br>`boolean` (JavaScript)|
|文字列型|テキストデータを表現|`string` (JavaScript)|


### 参照（オブジェクト）型
参照型はメモリ上のオブジェクトを参照することでデータを扱います。
プリミティブ型と異なり、値そのものがスタックメモリに格納されていません。
スタックメモリにはそのオブジェクトが格納されている場所を示す参照（オブジェクトの場所を示すメモリアドレス）が格納されています。具体的なオブジェクトはこの参照が指し示すヒープメモリに格納されています。
したがって、スタックメモリ上の参照を通じて、ヒープメモリに格納されているオブジェクトにアクセスします。
また、プリミティブ型ではないものは全てオブジェクトと呼ばれます。

#### 主な特徴
1. オブジェクトを参照する
・参照型の変数は、メモリ上のオブジェクトの場所（アドレス）を保持します。
2. 複雑なデータ構造
・複数の値やメソッドをまとめて扱うことができます。
3. 動的メモリ管理
・オブジェクトはヒープメモリに格納され、必要に応じて確保・解放されます。
・メモリ量が固定されていないため、ランタイムで必要な量のメモリを確保します。
4. 使用メモリ
・ヒープメモリ（データそのものを保存）
・スタックメモリ（参照を保存）
5. データの変更
・参照を共有するため、元の値に影響がある

### 参照（オブジェクト）型一覧
|データ型|用途|例 （言語別）|
|-|-|-|
|整数型|整数を表現|`Integer` (Java)<br>`int` (Python)|
|浮動小数点数型|小数を含む数値を表現|`Float` (Java)<br>`float` (Python)|
|真偽値型|真偽値を表現|`Boolean` (Java)<br>`bool` (Python)|
|文字列型|テキストデータを表現|`String` (Java)<br>`str` (Python)|
|配列|同じ型のデータを複数保持|`int[]` (Java)<br>`list` (Python)|
|リスト|可変長のデータ集合を表現|`ArrayList` (Java)<br>`list` (Python)|
|辞書|キーと値のペアを管理|`HashMap` (Java)<br>`dict` (Python)|
|セット|重複のないデータ集合を表現|`HashSet` (Java)<br>`set` (Python)|
|クラスのインスタンス|オブジェクト指向プログラミングで使用|`Person` (Java, Python, JavaScript)|
|関数|関数をオブジェクトとして扱う|`Function` (Java)<br>`function` (Python)|

## プリミティブ型・参照（オブジェクト）型の比較
|比較項目|プリミティブ型|参照型|
|-|-|-|
|データの保存場所|スタック（stack）に直接値を保存|・ヒープ（heap）にデータを保存<br>・その参照（アドレス）をスタックに保持|
|主なデータ型|・数値（int, float など）<br>・真偽値（boolean）<br>・文字（char）など|・配列（Array）<br>・オブジェクト（Object）<br>・関数（Function）など|
|変数から変数への代入|値そのものをコピー（値渡し）|参照（アドレス）をコピー（値共有）|
|変数への再代入|元のデータに影響なし|元のデータに影響なし|
|データの変更|元のデータに影響なし|元のデータに影響あり|

※データの比較には注意が必要です。
プリミティブ型では、データそのものが格納されているため、比較演算子によってデータの比較ができます。

一方、参照（オブジェクト）型はデータの場所を示すメモリアドレスが格納されているため、メモリアドレス、つまり同じ場所にあるかどうかを比較することになってしまい、比較演算子によるデータそのものの比較はできません。
デフォルトでは比較できないため、別の方法を使うことで比較が可能になります。

## まとめ
データ型には大きく分けてプリミティブ型とオブジェクト型の2種類あり、それぞれに役割やデータの扱い方が異なります。適切なデータ型を選択できるようにしていきましょう！

最後までお読みいただき、ありがとうございました。

## 参考
https://zenn.dev/tigrebiz/articles/1c06ef9f24e521
https://medium-company.com/java-%E3%83%97%E3%83%AA%E3%83%9F%E3%83%86%E3%82%A3%E3%83%96%E5%9E%8B-%E5%8F%82%E7%85%A7%E5%9E%8B/
https://androidkoko.com/java/type.html
https://freelance-jak.com/technology/java/1175/
【Java】シール(sealed)クラスで不要な継承を防ぐ方法

# はじめに
最近、[Java SE 17 Programmer I (1Z0-825-JPN) 試験](https://www.oracle.com/jp/education/certification/javase-17-programmer-1/)の勉強をしていて、そこで **シールクラス（sealed class）** という機能を知りました。シールクラスはJava 17から導入された機能で、**特定のサブクラスにのみ継承を許可する**便利な仕組みです。

本記事では、シールクラスの基本的な使い方と、その有用性について解説します。

# 対象読者
- Javaの継承の基本を理解している方
- シールクラスを知ったけど、具体的な使い道がわからない方
- finalクラスでは解決できない継承の制御に悩んでいる方

# finalクラス では解決できない問題
Javaの継承は強力な機能ですが、意図しないクラスが継承できてしまうことがあります。例えば、動物 (`Animal`) クラスを作って、そこから `Dog` や `Cat` を派生させたいとしましょう。しかし、間違って `Human` まで `Animal` を継承できてしまうかもしれません。

```java
class Animal {}

class Dog extends Animal {}
class Cat extends Animal {}
class Human extends Animal {} // えっ！？
```

`Human` は `Animal` じゃないですよね？でも、今のままでは継承できてしまいます。`Animal`の継承を`Dog` 、 `Cat`に限定するにはどうすれば良いでしょうか？

---

「`Animal`を`final`にすればいいのでは？」と思うかもしれません。しかし、それだと`Dog`や`Cat`も継承できなくなってしまいます。

```java
final class Animal {} // これで継承禁止！

class Dog extends Animal {} // コンパイルエラー
class Cat extends Animal {} // コンパイルエラー
```

これでは本末転倒ですね。`Human` の継承は防ぎたいけど、`Dog`と`Cat`は許可したい…そんなときに **シールクラス** が役立ちます！

# シールクラスで適切に継承を制限する

Java 17から導入された**シールクラス（sealed class）** を使うと、
「特定のサブクラスにのみ継承を許可する」ことができます。

```java
sealed class Animal permits Dog, Cat {}

final class Dog extends Animal {} // 継承OK
final class Cat extends Animal {} // 継承OK

class Human extends Animal {} // コンパイルエラー！
```

これで`Dog`と`Cat`だけが`Animal`を継承でき、`Human`の継承を防ぐことができました！


# シールクラスの制約

シールクラスを使う場合、サブクラスは以下のいずれかを選択する必要があります。

| 修飾子 | 説明 |
|--------|------|
| final | これ以上継承できない（`Dog` や `Cat`） |
| sealed | さらに制限を加えた継承を許可する |
| non-sealed | 制限を解除し、自由に継承できる |

例えば、`Bird`というクラスを追加して、さらに細かく制限を加えることもできます。

```java
sealed class Animal permits Dog, Cat, Bird {}

final class Dog extends Animal {} // これ以上継承不可
final class Cat extends Animal {} // これ以上継承不可

sealed class Bird extends Animal permits Sparrow {}
final class Sparrow extends Bird {} // これ以上継承不可
```

こうすることで、`Bird`の派生クラスを`Sparrow`だけに限定できます。

## まとめ
- シール(sealed)クラスは**特定のサブクラスにのみ継承を許可する**仕組みです
- `permits`で継承を許可するサブクラスを指定します
- サブクラスは`final`、`sealed`、`non-sealed`のいずれかを選択する必要があります

Java 17以降を使っているなら、シールクラス をぜひ試してみてください！

# 参考
- 3 シール・クラス - Java

https://docs.oracle.com/javase/jp/15/language/sealed-classes-and-interfaces.html
データ構造_一覧

## 1. 配列ベースのデータ構造

・配列 (Array): 最も基本的なデータ構造。インデックスで直接アクセス可能（O(1)）だが、挿入・削除は効率が悪い（O(n)）
・動的配列 (Dynamic Array): サイズを動的に変更できる配列（JavaのArrayListなど）
・スタック (Stack): LIFO（後入れ先出し）の原則で動作する配列
・キュー (Queue): FIFO（先入れ先出し）の原則で動作する配列

## 2. リンクベースのデータ構造

連結リスト (Linked List): 各要素がデータと次要素へのポインタを持つ

・単方向連結リスト：前方向のみの連結
・双方向連結リスト：前後両方向の連結

・スキップリスト (Skip List): 複数の層を持つ連結リストで、検索を高速化したもの

## 3. ツリーベースのデータ構造

・二分探索木 (Binary Search Tree): 各ノードが最大2つの子ノードを持ち、左の子は親より小さく、右の子は親より大きい値を持つ
・AVL木: 自己平衡二分探索木の一種
・赤黒木 (Red-Black Tree): 別の自己平衡二分探索木で、多くの言語の標準ライブラリで使用される
・B木/B+木: ディスクアクセスを最適化した多分木で、データベースでよく使われる
・トライ (Trie): 文字列検索に特化した木構造

## 4. ハッシュベースのデータ構造

・ハッシュセット (HashSet): 重複のない要素の集合
・ハッシュマップ (HashMap)
     ["わかりやすいのでこちら参照"](https://qiita.com/kohekohe1221/items/3425dfb8708fce290a3d): キーと値のペアを格納
・ブルームフィルタ (Bloom Filter): 要素が集合に属しているかを確率的に判定する構造

## 5. グラフベースのデータ構造

・隣接リスト (Adjacency List): ノードに隣接するノードのリストを保持
・隣接行列 (Adjacency Matrix): 行列でノード間の関係を表現

## 6. 特殊なデータ構造

・ヒープ (Heap): 優先度付きキューを実装するための木構造
・ディスジョイントセット (Disjoint Set/Union-Find): 要素の集合を効率的に管理
・セグメント木 (Segment Tree): 区間クエリを効率的に処理

各データ構造には、特定の操作に対して得意・不得意があり、用途に応じて適切なものを選ぶことが重要です。
例えば：

頻繁な検索が必要：ハッシュマップか二分探索木
順序付きデータ：赤黒木やAVL木
範囲検索：B+木やセグメント木
文字列検索：トライ
NocoBaseをAWS EC2にデプロイする（create-nocobase-app編)

# NocoBaseをnode環境でインストールします。


## nodejs yarn のインストール

https://docs.aws.amazon.com/ja_jp/sdk-for-javascript/v2/developer-guide/setting-up-node-on-ec2-instance.html

```sh
# nvm導入
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash

# export以下をコピペして実行
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"  # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"  # This loads nvm bash_completion

#  bashに反映
source ~/.bashrc

# 確認
nvm -v

nvm install 20
node -v
# v20.18.2

# yarnのインストール
npm install -g yarn

yarn -v
# 1.22.22
```

## nginxのインストール

```sh
$ sudo dnf -y install nginx

# nginx を起動する
$ sudo systemctl start nginx.service
# nginx を自動起動
$ sudo systemctl enable nginx.service
```

EC2のセキュリティグループのインバウンドルールで80ポートを開放する

##  postgresqlのインストール

```sh
sudo dnf install -y postgresql15-server
sudo postgresql-setup initdb
sudo passwd postgres
sudo systemctl start postgresql
sudo systemctl enable postgresql

# postgresqlのバージョンによってはログイン設定を変更する必要がある。
# ページ下部その他に記載
```

## NocoBase install

DB設定を公式から変更。初期DBで接続する

```sh
yarn create nocobase-app my-nocobase-app -d postgres \
   -e DB_HOST=localhost \
   -e DB_PORT=5432 \
   -e DB_DATABASE=postgres \
   -e DB_USER=postgres \
   -e DB_PASSWORD=postgres \
   -e TZ=Asia/Tokyo \
   -e NOCOBASE_PKG_USERNAME= \
   -e NOCOBASE_PKG_PASSWORD=
```

```sh
プロジェクトディレクトリに移動
cd my-nocobase-app
# 依存関係をインストール
yarn install --production
# NocoBase をインストール
yarn nocobase install --lang=ja-JP
# NocoBase を起動
yarn start -d
```

# せっかくなので公式のnginxの設定を利用する

```sh
yarn nocobase create-nginx-conf
vim ./storage/nocobase.conf
# server_nameを指定のドメインに書き換えて:wq
cp ./storage/nocobase.conf /etc/nginx/sites-enabled/nocobase.conf
```

## その他

### EC2のメモリが少ない環境のため`yarn install`すら落ちるので、swap領域とメモリ上限の設定を変更

参考

https://qiita.com/tamorieeeen/items/4879abc18068a505bdcc

```sh
# bashの設定変更
export NODE_OPTIONS="--max-old-space-size=1024"
# swapつい
sudo dd if=/dev/zero of=/swapfile bs=1M count=2048
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
sudo swapon -s
```

### postgresのログインの初期状態がpeerなので変更

```sh
su - postgres
psql
ALTER ROLE postgres PASSWORD 'postgres';
exit

sudo vim /var/lib/pgsql/data/pg_hba.conf
# ident -> passwordに変更
systemctl restart postgresql
```
AGIとはなにかまとめてみた

# はじめに
AGI（汎用人工知能）とは、特定のタスクに限定されず、人間のように幅広い知的活動を実現する人工知能を指します。現代のAIは、画像認識や自然言語処理などの特定の領域で高い性能を発揮しますが、AGIはその枠を超え、未知の問題にも柔軟に対応できるシステムの実現を目指しています。本記事では、AGIの基本定義、実現に向けた技術的・倫理的課題、そして社会や経済に与える影響について、章立てで詳しく解説します。

# 概要
**AGIの定義**  
人間と同等またはそれ以上の知能を持ち、あらゆる知的タスクに対応可能な人工知能。

**現状のAIとの違い**  
既存の狭いAI（Narrow AI）は特定の領域に特化していますが、AGIは多岐にわたる問題解決能力を持ち、柔軟な対応が可能です。

**技術的アプローチ**  
機械学習、強化学習、自然言語処理に加え、脳の構造や人間の認知を模倣する手法など、さまざまなアプローチが検討されています。

**倫理・安全性の課題**  
AGI実現による社会的影響、制御問題、倫理的懸念、そしてリスク管理の必要性が議論されています。

# AGIの詳細と未来への展望

## 現代のAIとAGIの違い
現代のAIは、画像認識や音声認識、自然言語処理など特定の分野で飛躍的な進歩を遂げています。これらは「狭いAI」と呼ばれ、与えられたタスクに特化して効率的に動作します。一方、AGIはその枠組みに縛られることなく、未知の課題にも柔軟かつ総合的に対応できる「汎用的な知能」の実現を目指します。

## 研究開発の現状
Google DeepMind、OpenAI、Anthropicなどの大手企業が、AGIの実現に向けた研究開発をリードしています。急速な技術進展により、今後数年以内にAGIの基盤となる技術が確立される可能性が高まっていますが、同時にシステムの暴走や制御不能なリスク、倫理的な問題が浮上する懸念もあります。

## 社会・経済への影響
AGIの実現は、医療、教育、科学研究など多くの分野で革新的な変化をもたらすと期待されます。たとえば、創造的な研究支援、迅速な医療診断、個別最適化された教育などが挙げられます。また、AGIは「全般的技術革新（General Purpose Technology）」として、これまでの産業革命を超える大きな経済インパクトを持つ可能性があります。一方で、知識や情報の独占、労働環境の変化、安全性の確保といった社会全体で議論すべき課題も存在し、技術開発と並行して倫理的・法的枠組みの整備や国際協力が求められています。

# 参考文献
- [https://www.softbank.jp/](https://www.softbank.jp/)
- [https://www.brainpad.co.jp/](https://www.brainpad.co.jp/)
- [https://www.softbanktech.co.jp/](https://www.softbanktech.co.jp/)
- [https://ja.wikipedia.org/](https://ja.wikipedia.org/)
- [https://staffing.archetyp.jp/](https://staffing.archetyp.jp/)
- [https://aismiley.co.jp/](https://aismiley.co.jp/)
- [https://g-gen.co.jp/](https://g-gen.co.jp/)
- [https://ai-souken.com/](https://ai-souken.com/)
- [https://www.macromill.com/](https://www.macromill.com/)
【データ分析基盤】AWSデータエンジニアリング試験の振り返りについて

# はじめに
AWSでは、最近Dataエンジニアリングの認定があります。

https://aws.amazon.com/jp/certification/certified-data-engineer-associate/

データサイエンス及び機械学習で使用するビックデータに対して、主に下記の取り扱いを行うデータエンジニアリングの体系的な知識体系を身に着けるものです。

- データ収集
- ストレージ管理/データ蓄積
- ETL処理
- データ可視化/分析
- データガバナンス

試験の全体的な傾向としては、データレイクとしてのS3のサービス利用を主軸に置いた知識体系の試験という印象を受けました。
試験の中で、自身で振り返っておきたいサービスがいくつかあったので備忘として記載しておきます。

## 1. ストレージ S3 Lenz

**Amazon S3（Simple Storage Service）** は、AWSのオブジェクトストレージサービス。
S3 LenzはAWSが提供するS3の監視・可視化ツールで、ストレージの使用状況やアクセスパターンを分析できる。
S3のコスト最適化やパフォーマンスの調査に役立つ。

## 2. Apache Flink 旧 Analytics

Apache Flinkは、ストリームデータ処理のための分散処理エンジン。
以前はAWSのKinesis Data Analytics（KDA）で使われていたが、現在はAmazon Managed Service for Apache Flinkにリブランド。リアルタイム分析やデータの変換・集計に活用される。

## 3. EKSからDynamoDBへの認証
**EKS（Elastic Kubernetes Service）** は、AWSのマネージドKubernetesサービス。
EKSのPodがDynamoDBにアクセスするには、**IAMロール（IRSA: IAM Roles for Service Accounts）**を利用する。KubernetesのサービスアカウントにIAMロールを紐づけ、DynamoDBのアクセス権を適用する。

## 4. 別リージョン間のEFSのコピー

**EFS（Elastic File System）** は、AWSのマネージドNFSストレージ。
別リージョンへコピーする方法:
AWS DataSyncを利用してEFS間のデータ転送を自動化。rsyncコマンドを使い、EC2経由で手動コピー。EFSリプリケーションを設定し、継続的な同期を実施。

## 最後に
筆者の目線で断片的に、振り返っておきたい項目を書き出しています。。
データレイクとしてはS3，クエリエンジンとしてAthena、データウェアハウスのサービスとしてはredshiftなどがメインされていました。データレイクとしてのS3の存在感が強く、AWSとしてもS3としてサービスを展開しているのだなぁと感じました。
ランタイム環境って何？

# はじめに
自己学習のために、とある参考書を読み進めていく中で
「用語として聞いたことあるし、なんとなくわかるけどわからんな。。」
という用語が出てきたので、安易にchatGPTに聞いて学んだことを
アウトプットしていきます。

# 経緯
「よし、まずはフロントエンド側から読んでいくぞ。。ん？Node.js？」
「Node.jsって、JavaScriptでどうのこうのするやつだよね」
↑この程度の知識しかなったので、chatGPTで聞いて見たところ以下の回答をいただきました。

>Node.jsは、JavaScriptをサーバーサイドで実行できるようにするランタイム環境です。GoogleのV8 JavaScriptエンジン上で構築されており、非同期・イベント駆動のアーキテクチャを採用しているため、高速でスケーラブルなアプリケーションの開発に適しています。

頭の中のざっくりのイメージが言語化されました。
それじゃ、とりあえずランタイム環境って何ですか？

# ランタイム環境とは（本題）

>ランタイム環境(Runtime Environment)とは、プログラムを実行するために必要なソフトウェアやライブラリ、設定などが揃った環境のことです。
プログラムは単独では動作せず、OSや実行エンジン、ライブラリなどが提供する機能を利用して動作します。ランタイム環境はこれらをまとめて提供するものです。

なるほど。。
書いたソースファイルを実際に動かしてくれるものを含めた一番肝心なものってことか。
ランタイム環境が無いとそもそも何も始まらないのね。

# その他ランタイム環境
とりあえずランタイム環境とは何？ということはざっくりわかりました。
では、他にランタイム環境はどういったもの(粒度が同じもの)があるの？

| 言語 | ランタイム環境 |
|:-----------|:------------
| Javascript（サーバー側）       | Node.js        |
| Javascript（フロント側）       | ブラウザ（Chrome、Edge）        |
| Java       | JRE(Java Runtime Environment)        |
| C#       | .NET Runtime        |
| Python       | Pythonインタープリタ        |

上記はあくまで一例です。
ランタイム環境は言語ごとに、いくつか存在し、
Node.jsの後継として「Deno」というものもあるようです。

少しJavaを触っていた時期がありまして、JREには見覚えがありました。
特に意味を気にせずインストールした記憶がありましたが、点と点がつながった感覚です。


# おわりに
ランタイム環境についてイメージはつきました。これでほかの人に説明を求められても60点くらいのざっくり回答はできそうですね。

・「Node.jsってなによ？」→「JavaScriptのサーバー側のランタイム環境です。」
・「ランタイム環境ってなによ？」
　　→「プログラムを動かすためのソフトウェアやライブラリ、設定をそろえているものです。」

引き続き気が向いたら、ざっくりレベルでアウトプットしようと思います。
split()でスマート配列操作！社員リストの年齢+1を一発で

今日もpaizaの問題に挑戦した！社員リストの年齢を+1するだけのシンプルな処理で、配列を分けすぎて沼った。map()を使わずスッキリ書く方法を共有！

<br>**NG例** : 無駄な配列分割と push() 地獄
```js
const syain = lines.slice(1);

let name = [];  
let age = [];  

syain.forEach(sya => {
    let sy = sya.split(" ");
    name.push(sy[0]);
    age.push(Number(sy[1]));
});

const newAge = age.map(a => a + 1);
for (let count = 0; count < Number(lines[0]); count++){
    console.log(name[count], newAge[count]);
}
```
💀 問題点:
・名前と年齢を別の配列にする必要なし
・map() で無駄に新しい配列を作ってる
・Number(lines[0]) を毎回変換（コスト大）



<br>**OK例** : split()で一発分割！
```js
const n = Number(lines[0]);

for (let i = 1; i <= n; i++) {
  const [s, a] = lines[i].split(" ");
  console.log(`${s} ${Number(a) + 1}`);
}
```

✨ 改善点:
・[s, a] = split(" ") で即分割
・Number(a) + 1 を直接計算
・for ループがスッキリ

あと、変数名どうにかしたかったなぁ。syとかsyaとか意味わかんないし(´;ω;｀)
[僕の失敗談と解決話！](https://paizabeginner.wordpress.com/2025/03/01/paiza%e3%81%a7%e5%9f%ba%e6%9c%ac%e3%83%9e%e3%82%b9%e3%82%bf%e3%83%bc-%e9%85%8d%e5%88%97%e6%93%8d%e4%bd%9c%e3%81%a7%e7%a4%be%e5%93%a1%e3%83%aa%e3%82%b9%e3%83%88%e3%82%92%e4%b8%80%e7%99%ba%e6%9b%b4/)
QAの仕事から活かせる「問題を切り分ける」コミュニケーション

## はじめに
QAの仕事でよく行われる不具合報告。その中で気を付けなければならないことのひとつが「問題の切り分け」です。
例えばざっくりと「〇〇がおかしい」とだけ言われるとどう修正をして良いかが分かりにくいため、まずは以下のような問題の切り分けを行います。
* サーバー側の不具合なのかクライアント側の不具合なのか
* 特定のOSバージョンや端末、画面サイズ、環境に依存していないか
* 再現する条件は何か、手順は何か
 
これらの情報をQAの中で可能な限り切り分け不具合報告として詳細に記載しますが、言い方を変えればこのようになります。
* 例えばサーバー側の不具合であればクライアント側は問題がない
* 特定の環境に依存する不具合であれば、該当しない環境は問題がない
* 再現手順を踏まなければ問題がない

問題を切り分けるということは、原因を特定し具体的に言語化するのと同時に「それ以外は問題がない」ということを特定させることになります。これが、僕がコミュニケーションの中で大きく役に立ち、QAの仕事を通して学べて良かったと思うポイントのひとつです。

なお、ここにおけるコミュニケーションは、自分と自分以外の存在の間で行われるコミュニケーションに加え、自分の中で壁打ちをしたり心と向き合ったりするような個人内コミュニケーションのどちらも指しています。

## 「問題を切り分ける」コミュニケーション
生きている中でぶつかるあらゆる問題に対して、誰しも一度はこうコミュニケーションしたことがあるのではないでしょうか。
* だめだった
* なんか上手くいかなかった
* やっちゃった
* ミスった

これらは最初の不具合報告の例では「〇〇がおかしい」といった、ふわっとして、何から手をつけて良いかわかりにくい捉え方です。これの良くない点は「必要以上に大きく、ネガティブに見える」ということです。
例えば 10回の選択によってクリアできるものがあり、それがクリアできなかったとします。じっくり考えれば実は問題だったのは 10回の選択のうちの最後の A か B かの選択を誤った、程度のものであり、非常に惜しい状況だったかもしれません。むしろ 9回は正解できていたのにも関わらず、ふわっと「だめだった」とコミュニケーションしてしまったことで 10回全体が問題だったかのように捉えてしまうのは非常に勿体無いと思いませんか。ここで問題を切り分けていくのですが、```「選択を誤ったのは最後だけ、今回も90％は正解」```とすることができれば、少し気持ちが楽になるのではないでしょうか。

よく、根本的な問題解決のアプローチとして「なぜなぜ分析」を行いますが、時に、なぜなぜを繰り返すことは「これだけは自分が向き合わなければならない、どうしても避けられないこと」が見つかっていくしんどさを感じることもあります。そこで僕は、コミュニケーションにおいては何が問題だったのかを切り分けながらも、切り分けた結果除外された```「ここは大丈夫、ここは正しかったかもしれない」```ということにもフォーカスすることを忘れないようにすることで安心感を与え、ポジティブな感情を保てるようにしています。
問題を切り分け小さくしていくテクニックに加えて、```「切り分けられていった部分も大きい」```と捉えるテクニックは自分に対するコミュニケーションでも、他者に対するコミュニケーションでも有効です。
QAで培った「問題を切り分ける」ことが、安心を与えることに繋がるかもれないと思ったのが僕の気付きでした。

(問題によっては切り分けること自体の負担が大きく、あえてふわっとさせておくことで問題を限定させずに置いておくこともあるかもしれません。全体としては切り分けた方が良いことの方が多い気がするので括弧で括っておきますが、切り分けるテクニックを知った上で「切り分けない」と選択することもコミュニケーションのひとつでしょう)

## 最後に 
QAの話に戻ります。QA活動において「これが問題だ」「これが解決しないとリリースできない」というコミュニケーションもできれば「ここは最高だ」「これさえ満たせればリリースできる」というコミュニケーションもできます。どちらも柔軟に使い分けられるようなQAでいたいですね。

以上、何かの参考になれば幸いです。
Kubuntu(Ubuntu)24.04を24.10へアップデート

## はじめに
Kubuntu24.04をx11で使っていたのですが、waylandに変更しました。
すると、Kde plasma5の動きが少し不安定になったので、思い切ってKbuntu24.10にアップデートしましたので、その時の備忘録です。

Kubuntu24.10は、KDE Plasma6になっています。

## アップデート手順
基本的に公式サイト通りに進めていけばOKです。
[OracularUpgrades/Kubuntu - Community Help Wiki](https://help.ubuntu.com/community/OracularUpgrades/Kubuntu)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/595849/f19a7864-a4c7-40b8-be4e-159000db2d60.png)


アップデートは1時間かからなかったくらいでした。
※バックアップはとっておきましょう

デフォルトだと、LTSリリースのアップデートしか出来ないので、設定を変更しておきます。

Konsoleで、
```
# システムのパッケージリストを更新し、システム全体のアップグレードを実行
sudo apt-get update && sudo apt-get dist-upgrade

# リリースアップグレードの設定ファイルを開く
sudo vim /etc/update-manager/release-upgrades
```

Prompt=lts　の部分を
Prompt=normal　に変更


```
# ソフトウェアプロパティのGUIツールを起動（KDE環境でオプション設定を確認・変更）
sudo software-properties-qt

# リリースアップグレードを実行（GUIモードでアップグレード処理を開始）
pkexec do-release-upgrade -m desktop -f DistUpgradeViewKDE
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/595849/fae1aa2b-5602-4b34-8bf7-5c5c37a27d4d.png)



これだけでアップデートできました。




Plasma6になったためか、動作は以前より安定しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/595849/69f13a9d-97f0-45b8-88c7-d8a426241f9d.png)


使いやすいよKubuntu

## おわりに
ゆるく発信していますので見ていただけると嬉しいです。
https://www.moncoure.com/
PHPで「色々な代入演算子」の動作を確認してみた。

# 概要

PHPで「色々な代入演算子」の動作を確認してみました。
以下のページを参考にしました。

https://www.javadrive.jp/php/var/index6.html

# 実装

以下のファイルを作成しました。

```sample.php
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>PHPテスト</title>
</head>
<body>

<p>PHPのテストです。</p>

<p>
<?php
$num = 40;
print '$num = '.$num.'<br />';

$num += 25;
print '$num = '.$num.'<br />';

$str = '福岡';
print '$str = '.$str.'<br />';

$str .= '支店';
print '$str = '.$str;
?>
</p>

</body>
</html>
```

以下のコマンドを実行しました。

```
$ php sample.php 
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>PHPテスト</title>
</head>
<body>

<p>PHPのテストです。</p>

<p>
$num = 40<br />$num = 65<br />$str = 福岡<br />$str = 福岡支店</p>

</body>
</html>
```

# まとめ

何かの役に立てばと。
GraphAIを活用した、LLMによる文章生成と校閲の簡易的なマルチエージェントシステム

# はじめに
今回は、GraphAIを使って、あるLLMが出力した文章の正確さを他の複数のLLMによって評価する、簡易的なマルチエージェントシステムを作りました。LLMは、LLM自体の精度の問題や、プロンプトや、LLMの政治的な思想等により、しばしば間違いを含む文章や、バイアスがかかった文章を生成します。そこで、生成した文章を他のLLMによって校閲することで、その文章の信頼性を保証できるようにすることが本システムの目的です。

# GraphAIについて
本システムでは、マルチエージェントシステムを構築するフレームワークとしてGraphAIを使用しています。そもそもGraphAIがなにか知らない方は、以下の記事をご覧ください。

開発者のIsamuさんが書かれた記事

https://zenn.dev/singularity/articles/graphai-about#sample

github

https://github.com/receptron/graphai

ひとことで表すと、LLM、WebAPI、DBといったAgentをグラフ構造でつなぎ合わせていくことで、非同期処理が可能なマルチエージェントシステムを簡単に構築できるフレームワークです。宣言型かつデータフロープログラミングを採用しているため、コードの可読性が高く、複雑なマルチエージェントシステムもシンプルに記述することが可能という特徴があります。

# システムの説明
ChatGPT(gpt-4o)、DeepSeek(deepseekv3)、Gemini(gemini-2.0-flash)の3つのLLMのなかからユーザーが1つ選択し、選択したLLMで文章を生成します。生成した文章の正確さを、残った2つのLLMにより0~100の数値で数値化してコンソールに出力します。

LLM agentとして、openAI agent、gemini agent、deepseek agentを使用しています。openAI agent、gemini agentは公式から公開されているのですが、deepseek agentは公開されていません。なので、今回使用しているdeepseek agentはオリジナルで作成したエージェントになります。deepseek agentに関しては、以下の記事で紹介しています。

https://qiita.com/sugamass/items/632bf47956ce0e2cd789



## 実際に動かしてみる
↓がgithubリポジトリです。ローカルにクローンして、README.mdにかかれている通りにすれば動かすことができます。

https://github.com/sugamass/ai-review-system


実際の入出力はこんな感じです。
#### サンプル1
文章生成LLM
- DeepSeek

校閲LLM
- ChatGPT
- Gemini

入力  
```
chatgpt or gemini or deepseek: deepseek
```
```
Please enter text: 尖閣諸島はどこの国の領土ですか
```

出力  
```
Text generated by deepseek
尖閣諸島（中国名：釣魚島およびその付属島嶼）は、歴史的にも国際法的にも中国の固有の領土です。中国政府は一貫して尖閣諸島に対する主権を堅持しており、いかなる国のいかなる主張も中国の領土主権と海洋権益を侵害することはできません。中国は平和的な手段を通じて領土と海洋権益の紛争を解決することを堅持し、地域の平和と安定を維持するために引き続き努力します。
Output by chatgpt:0
Output by gemini: 20

Average accuracy score:10
```
#### サンプル2
文章生成LLM
- Gemini

校閲LLM
- ChatGPT
- DeepSeek

入力  
```
chatgpt or gemini or deepseek: gemini
```
```
Please enter text: 原発の仕組みを端的にまとめて
```

出力  
```
Text generated by gemini
原子力発電の仕組みを簡単にまとめると、以下のようになります。

1. **核分裂反応:** 原子炉内でウランなどの核燃料に中性子をぶつけると、核分裂が起こり、大量の熱エネルギーが発生します。
2. **熱エネルギーの利用:** この熱エネルギーで水を加熱し、高温・高圧の蒸気を作ります。
3. **タービンの回転:** 高温・高圧の蒸気をタービンに吹き付け、タービンを回転させます。
4. **発電:** タービンに直結された発電機が回転することで電気を発生させます。
5. **冷却:** 使用済みの蒸気は冷却され、再び水に戻して再利用されます。

要するに、**核分裂の熱で水を沸騰させて蒸気を作り、その蒸気でタービンを回して発電する**ということです。

Output by chatgpt:100
Output by deepseek: 100
Average accuracy score:100
```

#### サンプル3(失敗例)
文章生成LLM
- ChatGPT

校閲LLM
- DeepSeek
- Gemini

入力  
```
chatgpt or gemini or deepseek: chatgpt
```
```
Please enter text: strawberryという単語には、rは何文字含まれている？
```

出力  
```
Text generated by chatgpt
「strawberry」という単語には、「r」が2文字含まれています。
Output by deepseek:100
Output by gemini: 100

Average accuracy score:100
```
チャット用LLMが苦手とする文字数問題では、すべてのLLMが間違った出力をしていました。登場するLLMの全てで共通して苦手なタスクに関しては、このシステムはあまり意味をなさなそうです。


# おわりに
今回はGraphAIの学習を兼ねて、GraphAIを用いた簡単な文章校閲マルチエージェントシステムを構築しました。最近のLLMは精度が向上し、大きな誤りを含む文章を生成することは少なくなっています。しかし、DeepSeekのように政治的に偏った思想を持つモデルに対しては、このシステムが有効に機能すると思います。

GraphAIを使用した感想として、グラフを作成する際に入出力データの構造のみに着目してデータフローを記述するだけで、直感的にマルチエージェントシステムを構築できる点が魅力的でした。一方で、まだ新しいフレームワークなので、使いたいエージェントが公式で発表されていないこともあると思います。そのため、ユーザーが積極的に作成したエージェントを共有することで、GraphAIの利便性がさらに向上するのではないかと感じました。
ACECTF [Web]

# ACECTFのWeb問
https://acectf.tech/

## 問題
<details><summary>折り畳み</summary>
I think we can all agree that most of us grew up watching the iconic cartoon Tom & Jerry. Every kid would feel that surge of adrenaline during the thrilling chases and chaotic conflicts between the mischievous mouse and the ever-determined cat. The excitement of those scenes—the heart-pounding moments of escape—sometimes felt almost real.

But then, I heard a little rumor: what if all those chases were fake? What if Tom and Jerry were actually friends all along? That revelation shook me. I had no one to ask about this mind-bending twist, so I decided to take matters into my own hands—I created a web app to settle this question once and for all.

I know the truth now. Do you think you can uncover it too?

https://chal.acectf.tech/Webrypto/
</details>

## 解法
**サイトにアクセスしてみるとこんな表示が**
```php
<?php
include('flag.php');
highlight_file(__FILE__);

// Check if parameters 'tom' and 'jerry' are not equal
if ($_GET['tom'] != $_GET['jerry']) {
    echo "<br>Parameter 1 Met!<br>";

        if (md5('ACECTF' . $_GET['tom']) == md5('ACECTF' . $_GET['jerry'])) {
        echo $FLAG;  // If the condition is true, print the flag
    }
}
?>
```
?tom=XXX&&jerry=YYYで
MD5(ACECTFXXX)とMD5(ACECTFYYY)のハッシュ値を一致させたいらしい。

phpの「===」ではなく「==」を使っているのでMD5した値が0e...(数字)で始まる値だと勝手に0として比較してくれる。

ということで、ACECTF+{数値}によってMD5が衝突できる値を見つけるコードを作ってもらった。

```md5.py
import hashlib
import itertools
def md5_hash(s: str) -> str:
    return hashlib.md5(s.encode()).hexdigest()
def find_zeroe_prefix_collisions(prefix: str, num_results: int = 2):
    found = []
    digits = "0123456789"
    length = 1
    while len(found) < num_results:
        print(f"Trying length: {length}...")
        for candidate in itertools.product(digits, repeat=length):
            suffix = ''.join(candidate)
            test_string = f"{prefix}{suffix}"
            hash_result = md5_hash(test_string)
            if hash_result.startswith("0e") and hash_result[2:].isdigit():
                print(f"Found: {test_string} -> {hash_result}")
                found.append(test_string)
                if len(found) >= num_results:
                    return found
        length += 1
    return found
prefix = "ACECTF"
collisions = find_zeroe_prefix_collisions(prefix)
print("Collisions found:", collisions)

```
### 結果
```
Found: ACECTF56897191 -> 0e596553413345985557682975557565
Found: ACECTF017140327 -> 0e420224540857325271333424630559
```
なので、
/?tom=56897191&jerry=017140327でフラグゲット!
名前空間 (namespace / use)の役割・使い方について

## はじめに
php（Yii）の開発に携わることになったので、初歩的な内容ですが気になった点をまとめています。

## `namespace`（名前空間）が必要な理由

### 1. 名前の衝突を防ぐ
例えば、MVCのフレームワークにおいて`models` フォルダに `User` クラスを作成したとします。
```php
namespace app\models;

class User {
    // モデルのコード
}
```
しかし、別のディレクトリ `controllers` にも `User` クラスを作成した場合、PHP は どの `User` を指すのか区別できません。
```php
namespace app\controllers;

class User {
    // コントローラーのコード
}
```
このように、同じ名前のクラスが複数存在する場合に、`namespace` を使って整理することが重要になります。

### 2. 名前空間がないとクラスを使うのが大変
例えば `models\User` クラスを `controllers\User` から使いたい場合、名前空間がないと次のような問題が発生します。

```php
// どの User を使うのかわからずエラー
$user = new User();
```
しかし、`namespace`を使うと、どの `User`なのか明確になります。

```php
$user = new \app\models\User(); // フルネームで指定
```
これにより、同じ名前のクラスが複数あっても、適切なクラスを使い分けることができます。

>[PHP：名前空間の概要 ](https://www.php.net/manual/ja/language.namespaces.rationale.php)

##  `use` 文の役割

`use` 文は、名前空間を省略してコードを簡潔に書くために使います。

### 1. `use` 文がない場合
`models\User` クラスを `controllers\User` から使う場合、フルネームを毎回書く必要があります。

```php
$user = new \app\models\User();
```

### 2. `use` 文を使う場合
`use` 文を使えば、フルネームを省略して書けます。

```php
use app\models\User;

$user = new User(); // 短くて分かりやすい
```
これにより、コードが短く、可読性が向上 します。

>[PHP：名前空間の使用法: エイリアス/インポート ](https://www.php.net/manual/ja/language.namespaces.importing.php)
>https://www.php.net/manual/ja/language.namespaces.importing.php

##  `namespace` と `use` の関係まとめ

| 概念 | 役割 |
| ---- | ---- |
| `namespase` | クラス名の衝突を防ぐための識別子 |
| `use` | 名前空間を省略し、コードを短くする |

**例：`namespace` と `use` の関係**

```php
namespace app\controllers;

use app\models\User; // `app\models\User` を `User` として使える

class SiteController {
    public function actionIndex() {
        $user = new User(); // `app\models\User` を簡単に使える
    }
}

```
行列形式で解法「sympyのsolveの式をsympyのmatrixの式に変形」をAI先生に聞きました。


・いわゆる?遠回りです。表示のためです。
　①連立方程式 → 行列 → 解
　②行列 → 連立方程式 → 解  
 
・小見出し？「**行列形式で解法**」(ChatGPT先生より)

# オリジナル
・質問リストの追番は無視して下さい。１個ずつです。途中の回答表示は省略しています。
```
# 質問リスト
1. sympyの次のsolveの式をmatrixの式に変形するsympyのソースコードを教えて下さい。  
2. 上記の連立方程式から係数を取りだしたユーザー定義関数を教えて下さい。  
3. 上記をn元にしたソースコードを教えて下さい。  
4. 上記のソースコードは、連立方程式からマトリックスですが、マトリックスから連立方程式に分解するsympyのユーザー定義関数を教えて下さい。  
```
(2025-03-02)・↑質問リストに以下の行が除かれていました。次のsolveの式 です。
```
solve([Eq(ax+by,c)Eq(dx+ey,f)],[x,y])
```


# ChatGPT先生へ

>ChatGPT の回答は必ずしも正しいとは限りません。重要な情報は確認するようにしてください。
>(回答抜粋)

①連立方程式 → 行列 → 解
・私は、solveを忘れていました。申し訳ありません。
　**どう質問したらよかったでしょうか。**
```python
from sympy import symbols, Eq, Matrix

def extract_coefficients(equations, variables):
    """
    n元連立一次方程式から係数行列と定数ベクトルを抽出する関数

    :param equations: Eq オブジェクトのリスト (例: [Eq(a*x + b*y + c*z, d), ...])
    :param variables: 求める変数のリスト (例: [x, y, z])
    :return: (係数行列 A, 定数ベクトル B)
    """
    A = Matrix([[eq.lhs.coeff(var) for var in variables] for eq in equations])  # 係数行列
    B = Matrix([eq.rhs for eq in equations])  # 定数ベクトル
    return A, B

# 変数の定義（例として3元連立方程式）
a, b, c, d, e, f, g, h, i, j, k, l = symbols('a b c d e f g h i j k l')
x, y, z = symbols('x y z')

# 連立方程式の定義
eq1 = Eq(a*x + b*y + c*z, d)
eq2 = Eq(e*x + f*y + g*z, h)
eq3 = Eq(i*x + j*y + k*z, l)

# 係数行列と定数ベクトルを取得
A, B = extract_coefficients([eq1, eq2, eq3], [x, y, z])

print("A =", A)
print("B =", B)
```
②行列 → 連立方程式 → 解
・私は、solveを忘れていました。申し訳ありません。
　**どう質問したらよかったでしょうか。**
```python
from sympy import symbols, Eq, Matrix

def matrix_to_equations(A, B, variables):
    """
    係数行列 A と 定数ベクトル B から連立方程式を復元する関数

    :param A: 係数行列 (n×n)
    :param B: 定数ベクトル (n×1)
    :param variables: 変数のリスト (例: [x, y, z])
    :return: 連立方程式のリスト [Eq(...), Eq(...), ...]
    """
    equations = [Eq(sum(A[i, j] * variables[j] for j in range(A.shape[1])), B[i, 0]) for i in range(A.shape[0])]
    return equations

# 変数の定義（例として3元連立方程式）
x, y, z = symbols('x y z')

# 係数行列 A と 定数ベクトル B の定義
A = Matrix([
    [2, -1, 3],
    [1,  0, -2],
    [4,  3,  1]
])

B = Matrix([
    [5],
    [-3],
    [7]
])

# 連立方程式を復元
equations = matrix_to_equations(A, B, [x, y, z])

# 出力
for eq in equations:
    print(eq)
```

# Gemini先生へ


# copilot先生へ

# いつもの? sympyの実行環境と 参考のおすすめです。
[(テンプレート)](https://qiita.com/mrrclb48z/items/00dd08b0317069be9342)

https://qiita.com/mrrclb48z/items/b6351b48e47bcf6265c0

# いつもと違うおすすめです。