OmniAICreator/Qiita-1.07M huggingface dataset:
【🐝 Agency Swarm】Genesis Agencyで作る！最適なWebサイト制作エージェンシーの自動定義構築

## はじめに
Agency Swarmのジェネシスエージェンシー機能を使えば、自然言語での指示だけでWebサイト制作用のAIエージェンシーを簡単に構築できます。本記事では、実際のセットアップから具体的なエージェント構成まで、詳しく解説します。

<blockquote class="twitter-tweet" data-media-max-width="800"><p lang="ja" dir="ltr">AIエージェントフレームワーク「Agency Swarm」で遊んでみる！！！①<br>エージェントフレームワークがエージェントの定義を提案してくれた！！<br>この機能は初めてかも！！！ <a href="https://t.co/1eNVwHwbT8">https://t.co/1eNVwHwbT8</a> <a href="https://t.co/YsMSsFI3wo">pic.twitter.com/YsMSsFI3wo</a></p>&mdash; Maki@Sunwood AI Labs. (@hAru_mAki_ch) <a href="https://twitter.com/hAru_mAki_ch/status/1888665402420691184?ref_src=twsrc%5Etfw">February 9, 2025</a></blockquote> 

## Genesis Agencyによるエージェンシー作成手順

### 1. 基本セットアップ
```python
from agency_swarm.agency.genesis import GenesisAgency
agency = GenesisAgency(with_browsing=False)
demo = agency.demo_gradio(height=900)
```

### 2. エージェンシー要件の入力
```bash
以下の構成でWebサイト制作を行うエージェンシーを作成してください：
- プロジェクトマネージャー（クライアントとの窓口）
- フロントエンドデベロッパー
- バックエンドデベロッパー
- UIデザイナー
GitHubのAPIとの連携も必要です。
```

## 生成されるWebDevAgencyの構成

### ミッションと目標
WebDevAgencyは、クライアントのニーズに応える高品質なWebサイトを制作することを目指します。プロジェクトマネージャーを中心に、各専門エージェントが効率的に連携してプロジェクトを進行します。

### エージェンシー構造
```python
agency = Agency([
    pm,  # プロジェクトマネージャーがユーザーとの窓口
    [pm, frontend],  # PMとフロントエンド開発者の連携
    [pm, backend],   # PMとバックエンド開発者の連携
    [pm, designer],  # PMとUIデザイナーの連携
    [frontend, backend],  # フロントエンドとバックエンドの連携
    [frontend, designer], # フロントエンドとデザイナーの連携
])
```

### エージェントの役割と使用ツール

#### 1. プロジェクトマネージャー（PM）
- **役割**: クライアントとのコミュニケーション、プロジェクト進行管理
- **ツール**: GitHub API（プロジェクトのリポジトリ管理）
- **特徴**: チーム全体のハブとして機能

#### 2. フロントエンドデベロッパー
- **役割**: ユーザーインターフェースの実装
- **ツール**: GitHub API（プルリクエスト、ブランチ管理）
- **連携**: バックエンド開発者、UIデザイナーと直接連携

#### 3. バックエンドデベロッパー
- **役割**: サーバーサイドの機能実装
- **ツール**: GitHub API（プルリクエスト、ブランチ管理）
- **連携**: フロントエンド開発者との密接な協力

#### 4. UIデザイナー
- **役割**: デザインの作成とプロトタイピング
- **ツール**: GitHub API（デザインファイルの管理）
- **連携**: フロントエンド開発者と直接連携

## 特徴的な連携フロー

1. **柔軟なPM制**
   - PMを介さない直接的な連携も可能
   - 状況に応じた効率的なコミュニケーション

2. **効率的な開発フロー**
   - フロントエンドとバックエンドの直接連携
   - 開発スピードの向上

3. **デザイン実装の最適化**
   - デザイナーとフロントエンド開発者の直接連携
   - デザインの正確な実装を実現

## まとめ
Genesis Agencyを活用することで、複雑なWebサイト制作エージェンシーを簡単に構築できます。この構成により、効率的な開発プロセスと円滑なコミュニケーションが実現でき、GitHubとの連携でコード管理やバージョン管理も適切に行えます。さらに、必要に応じてQAエンジニアやセキュリティスペシャリストなども追加可能な柔軟な構成となっています。


## リポジトリ

https://github.com/VRSEN/agency-swarm

<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
React nativeとExpoの構成でreact-native-app-intro-sliderとexpo-routerの組み合わせでウェルカムページを実装する方法を解説

# ライブラリをインストール

## react-native-app-intro-slider
```
npm install react-native-app-intro-slider
```
## Expo Router
古いバージョンのexpoを使っていなければ、デフォルトで入っている。手動でインストールする場合はこちらの記事を参照

https://docs.expo.dev/router/installation/#quick-start



## ディレクトリ構成
```
app ━ welcomePage.jsx
    ┣ home.jsx
```

## コード
```React
import React from 'react';
import { StyleSheet, View, Text } from 'react-native';
import AppIntroSlider from 'react-native-app-intro-slider';
import { useRouter } from 'expo-router';


const slides = [
    {
        key: 'one',
        title: 'Title 1',
        text: 'Description.\nSay something cool',
        backgroundColor: '#03a9f4',
    },
    {
        key: 'two',
        title: 'Title 2',
        text: 'Other cool stuff',
        backgroundColor: '#009688',
    },
    {
        key: 'three',
        title: 'Rocket guy',
        text: 'I\'m already out of descriptions\n\nLorem ipsum bla bla bla',
        backgroundColor: '#03a9f4',
    }
];

const WelcomePage = ({ navigation }) => {

    const _renderItem = ({ item }) => {
        return (
            <View style={styles.slide}>
                <Text style={styles.title}>{item.title}</Text>
                <Text style={styles.text}>{item.text}</Text>
            </View>
        );
    }
    const router = useRouter();
    const _onDone = () => {

        router.push('/home');
    }

    return (

        <AppIntroSlider renderItem={_renderItem} data={slides}  bottomButton　onDone={_onDone}/>

    );
};

export default WelcomePage;

const styles = StyleSheet.create({
    slide: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
    },
    title: {
        fontSize: 22,
        textAlign: 'center',
    },
    text: {
        textAlign: 'center',
    },
});
```

## コード解説
```React
    const router = useRouter();
    const _onDone = () => {

        router.push('/home');
    }

    return (

        <AppIntroSlider renderItem={_renderItem} data={slides}  bottomButton　onDone={_onDone}/>

    );
};
```
onDoneが押されると関数_onDoneが発火してexpo-routerで"home"画面へ画面遷移を行う簡単な仕組み

画面遷移を行うライブラリにはreact navigationがあるが、使い方が難しいので避けた。expo-routerはシンプルな使いごこちでとても手触りが良い

## 参照リンク

https://github.com/tralljf/react-native-app-intro-slider

https://docs.expo.dev/router/introduction/
【メモ】パパっとAPIKeyを作る方法

## 概要
簡単にAPIキーを用意する方法のめも

## 方法

```bash
python -c "import os, base64; print(base64.urlsafe_b64encode(os.urandom(64)).decode())" 
```

実行結果：
```
VZn-AM63pKZZlUhWKqNFkLOfIVV9Xc2Roh8DPuR-6d2qSzLLJksM91YfYnqDCcUl15t8vcZIt1ArWHzJ6kFW8A==
```
論文用: latexで()の前にスペースを入れる正規表現

# 概要
卒論執筆時に()の前にはスペース( \\, )を入れないといけない言われたため、それを自動でしてくれる正規表現をChatGPTに作ってもらいました。使っていてかなり便利なので残しておきます。
overwolfで動作確認済みです

# 要件
- ( を \\,( に変換する。
- すでに \\,( なら変換しない。
- 数式の挿入である, \\( には反応しない。

# コード
### 検索
```
(?:(?<=^)|(?<=[^\\,\s]))\s*\(
```

### 置換
```
\\,(
```

# 使い方
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404889/97f3c323-da8c-7b21-053f-c26a42901cd5.png)
VSCode で Language Server (Pylance) が動かなくなって悩んだ

## 現象

Visual Studio Code で Python の Language Server である Pylance が起動しなくなってしまい、数日悩みました。

OUTPUT のプルダウンには `Python Language Server` が表示されなくなっていました。

OUTPUT の `Extension Host` には `Error: Channel has been closed` といったエラーが出ていました。

## 解消手順

 1. `~/.vscode/argv.json` に `ms-python.python=debug` のようなログレベルの設定があるのを確認。他には大した設定が書かれていないのを確認
 2. `~/.vscode/argv.json` を削除
 3. `⌘+Shift+P` で `>Python Clear Cache and Reload Window` を実行

で動くようになりました。

## 再現手順

問題は手元の Mac で起きていて、Windows では再現しませんでした。
macOS のバージョンは `Ventura 13.7.2` と `Sequoia 15.3` です。途中でバージョンを上げました。1台の Mac です。

`OUTPUT` から `Python` を選び、歯車アイコン :gear: でログレベルを `Warning` に変更 (どれでもいいようです)、`Set As Default` で保存すると `~/.vscode/argv.json` に以下のように保存されます。

```json
  "log-level": [
    "ms-python.python=warn"
  ]
```

この状態で `>Python Clear Cache and Reload Window` を実行すると Pylance が起動しなくなります。

JSON を編集して設定を消しても直りませんでした。

## 解消までに試したこと

### プロファイル

新しい[プロファイル](https://code.visualstudio.com/docs/editor/profiles)を使い、最小限の機能拡張だけいれて試しても直りませんでした。

### Trust Mode

`⌘+Shift+P` で `>Workspaces: Manage Workspace Trust` を実行、ワークスペースを `Restricted Mode` (信用しない) に切り替えると、問題なく起動することがわかりました。

### シェルの設定を変えてみる

`.zshrc` や `.zprofile` など、全てのシェル関係のファイル名を変え、シェルの影響を受けないようにしても直りませんでした。

シェルの設定を変える時は、`HISTSIZE` が小さくなって、コマンド履歴が消えないように要注意です。

### Python ランタイムの変更を検討

Python のバージョンを管理している `mise` や `homebrew` の影響を受けているのではと疑いましたが、`mise` はともかく `homebrew` の `python` は依存が多くて気軽には消せませんでした。

### OS のバージョンを上げる

OS を `Ventura 13.7.2` から `Sequoia 15.3` にアップデートしても直りませんでした。

### デバッガでコードを見てみる

`Help > Toggle Developer Tools` のコンソールから、エラー行を開いてブレイクポイントを設定し、ソースを見たりしたのですが、わからず。

### :star2: ポータブルモードを試す

[ポータブルモード](https://code.visualstudio.com/docs/editor/portable)に切り替えた所、問題なく動くようになったので、やはり設定が悪いのだろうと当たりを付けました。

Mac だと `Visual Studio Code.app` を空のフォルダにコピーして、同じ階層に `code-portable-data` フォルダを作るだけでした。

### 設定ファイルを一新する

まっさらな環境になるよう、`~/.vscode/` と `~/Library/Application\ Support/Code` の両方をリネームして再起動、`>Python Clear Cache and Reload Window` を実行したら動くようになりました。

過去の設定を捨てて一からやり直しても良かったのですが、`~/.vscode/` を見ていたところ、`argv.json` が怪しそうだったので、これを消して起動し直したら動くようになりました。

## どうしたらもっと早く解決できたか

普段使う道具の、設定がどこに保存されていて、どういう役割なのかくらいは把握しておかないと、いざという時に苦労するなと思いました。

`~/.vscode/` と `~/Library/Application\ Support/Code` がどういう使い分けなのかは、調べてもよくわかりませんでしたが……。

`~/.vscode/` には、機能拡張が保存されています。また、起動オプションに関わる `argv.json` が保存されています。起動時に必要な設定、クラッシュレポーターやログレベルがここに保存されるようです。 `~/.vscode-cli/` にもコマンドラインの設定らしきファイルがありますが、よくわかりません。

`~/Library/Application\ Support/Code/User/` にはユーザレベルの設定 `settings.json` が保存されています。

OUTPUT で見られるログは、`~/Library/Application\ Support/Code/logs/{起動時刻}/window{番号}` 以下にありました。

ポータブルモードを使うと、設定の一切合切を1つのディレクトリにまとめられます。普段からこちらを使う方が明快なのでは、という気もしました。
[Nomad Sculpt]ハイポリの頂点ペイントをローポリにベイクする手順

# 概要
NomadSculptでハイポリからローポリに変換するとペイント機能で描いてた頂点ペイントが
![IMG_0030.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/77389f04-d4d7-77b6-7405-019cb5de7982.png)
ぼろぼろに崩れてしまいます。
![IMG_0033.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/c9955880-0711-3269-e5d4-ca3d0193a578.png)
こういう場合はベイク機能を使えばローポリへ良い感じに引き継ぐことができます。

# 本文
まずはローポリを作成します。クローン機能を使ってハイポリを複製して、ハイポリは非表示にしておきます。
![IMG_0031.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/36d6a1a9-c8e8-a60e-aab0-c61b5754b734.png)

デシメーションを複数回押してポリゴン数を減らします。
![IMG_0032.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/b3c357e8-528c-af77-dd6c-0a08070cbcfe.png)
今回は23.8kから5.9kまで減らしました。見事に頂点ペイントが崩れてしまっています。
![IMG_0033.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/4386d26f-ab5f-8e50-1396-164d277465a1.png)
ここから頂点ペイントを復元していきます。まずは先ほど非表示にしていたハイポリの表示をONにします。
![IMG_0034.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/a67b4a41-1ba8-0dae-2879-15ecb26d4a9f.png)
UV展開-UVAtlasの「展開」を押します。さっきまでと違うテクスチャ表示になりますが
![IMG_0035.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/23a37289-0536-ab3a-f26a-b0c354a7ba7b.png)
この「UVボタン」を押したら頂点ペイントの表示に戻ります。
![IMG_0036.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/07c335c0-4106-4eed-942c-48c38534ff2a.png)
最後にベイク→テクスチャの「高解像度から」を押したらローポリの頂点ペイントが綺麗な状態になりました！:raised_hands_tone2:
![IMG_0038.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/bef79a43-0cf5-3414-1005-5cb967cd1e04.png)

# 補足
リメッシュ機能やQuadRemesherを使用した時の頂点ペイントの崩れもこの方法で直せます！
![IMG_0042.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/90f48418-163f-8036-7bc6-1d61b48cc261.png)


参考動画
[Tutorial 1: MorphinApp (3D animation for mobile)](https://www.youtube.com/watch?v=BglhkUoJi_M&t=97s)
めっちゃ時間がかかる pip install flash_attn をどのようにインストールしたか？


### 課題: `flash_attn`のインストールにおいてメモリが足らなくなっている


原因は、内部的に`ninja`を用いた並列コンパイルを行っており、各プロセスがメモリを確保しているようで、結果としてメモリが足らなくなっていた。

```bash
pip install flash_attn
```

この後、別のターミナルでメモリ量を確認する

```bash
$ free -h
               total        used        free      shared  buff/cache   available
Mem:            56Gi        51Gi       5.0Gi       0.0Ki       269Mi       4.7Gi
Swap:          2.0Gi       1.5Gi       544Mi
```

以下に対策を示す。本質は対策2であり、実際は対策1は不要かも・・・

### 対策1: Swap量を増やす

SWAP を16GB に増やすこととした

```bash
sudo swapoff -a
sudo fallocate -l 16G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
```

以下でswapが増えたことを確認する

```bash
free -h
```

再起動すると、ものに戻るので注意


### 対策2: ninjaの並列数を調整する

並列数を今回4としているが、実際は並列数と消費メモリ量, 最大メモリ量と相談しながら決めること

```bash
export MAX_JOBS=4
```


### pip install

```bash
pip install flash_attn -v
```
rust printしたい内容が順番通りに表示されない

こうゆうプログラムを実行してみたんすよ

```rs
use std::io;

fn main() {
    let subjects: [&str; 3] = ["国語", "社会", "理科"];
    let mut scores: [i32; 3] = [0; 3];

    for (i, subjects) in subjects.iter().enumerate() {
        print!("{}の点数=", subjects);
        let mut input = String::new();
        io::stdin().read_line(&mut input).unwrap();
        scores[i] = input.trim().parse::<i32>().expect("TypeError");
    }

    let sum: i32 = scores.iter().sum();
    let averave = sum as f64 / 3 as f64;

    println!("合計点は{}点です。\n平均点は{}点です。", sum, averave);
}
```

そしたら、`print!("{}の点数=", subjects);`の内容が表示されない！！！

### なんでやねん

出力は以下のようになりました。
```
90
50
60
国語の点数=社会の点数=理科の点数=合計点は200点です。
平均点は66.66666666666667点です。
```

println!を使うと問題なくできるけど、print!を使うとできない！
でも、国語の点数=2みたいに、「=」のすぐ右に入力できるようにしたい

[ちなみに全く同じ内容の記事も見つけました](https://qiita.com/V_lasergun/items/bb2483f3ce6bd377c863)

---

となりましたので調べました（ＣｈａｔＧＰＴ）

どうやらバッファリングというものが関係しているらしい

gpt answer

Rust の print! マクロは 標準出力 (stdout) をバッファリング します。
つまり、出力をある程度まとめてから表示 する仕組みになっています。

バッファリングとは？

- print! の出力はすぐに画面に表示されず、一時的にメモリ上のバッファ (buffer) に溜められる。
- バッファがいっぱいになるか、改行 (\n) が含まれると、そのタイミングで出力が画面に表示される。
- これは効率的な入出力を行うための最適化です。もし1文字ごとに画面へ出力すると、処理速度が低下する可能性があるため、ある程度まとめて処理される仕組みになっています。

---

flushをつかえばいいのねー
なるほどねー

これらをを踏まえて、
以下のように変更したら、問題なく動作するようになりました。
Rustむずかしー！

```rs
//use std::io;
use std::io::{self, Write};

fn main() {
    let subjects: [&str; 3] = ["国語", "社会", "理科"];
    let mut scores: [i32; 3] = [0; 3];

    for (i, subjects) in subjects.iter().enumerate() {
        print!("{}の点数=", subjects);
        io::stdout().flush().unwrap(); // ここでフラッシュ
        let mut input = String::new();
        io::stdin().read_line(&mut input).unwrap();
        scores[i] = input.trim().parse::<i32>().expect("TypeError");
    }

    let sum: i32 = scores.iter().sum();
    let averave = sum as f64 / 3 as f64;

    println!("合計点は{}点です。\n平均点は{}点です。", sum, averave);
}
```

出力
```
国語の点数=90
社会の点数=2
理科の点数=45
合計点は137点です。
平均点は45.666666666666664点です。
```
偽のエラーメッセージや偽のキャプチャ画面などを使ったソーシャルエンジニアリングについて

最近よく見る偽のエラーメッセージやキャプチャ画面について簡単に紹介します。
セキュリティに関わっていない方でも読みやすいように書いてあります。

## ClickFixについて
偽のエラーメッセージやキャプチャ画面を使って、悪意あるコードを実行させようとする手法です。
昨年あたりからよく見かけるようになり、日本語で書かれているものも確認しています。
## ClickFixの例
### 偽のブラウザエラーメッセージ(Chrome)
Chromeなどのブラウザのエラーメッセージを装って、悪意あるコードを実行させようとします。
![スクリーンショット 2025-02-07 11.16.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274361/cee02542-0e44-7b3d-211c-9cd656a1646e.png)
![スクリーンショット 2025-02-07 11.16.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274361/05046ee5-0bb8-43b6-9047-2d91e68df1c3.png)

「修正をコピー」をクリックすると、以下の悪意あるコートがコピーされます。
![スクリーンショット 2025-02-07 11.19.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274361/41d35762-d79e-ea5e-e721-ee35a6f3b26b.png)

### 偽のキャプチャ画面(Notion + Cloudflare Turnstile)
NotionとCloudflare Turnstileを装って、悪意あるコードを実行させようとします。
![スクリーンショット 2025-02-07 23.04.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274361/3471bf1e-bf9e-652f-5420-baa99c427632.png)
![スクリーンショット 2025-02-07 23.04.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274361/af89fe5b-c321-f1cc-5970-56480345e637.png)

コピーされる悪意あるコードは以下のようになっています。
![スクリーンショット 2025-02-07 23.06.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274361/5f3384f6-cd3e-c308-d11c-209a0320e3a1.png)


### 偽のキャプチャ画面(reCAPTCHA)
reCAPTCHA画面を装って、悪意あるコードを実行させようとします。
![スクリーンショット 2025-02-07 10.33.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274361/243d7daa-ef1c-6767-7ce5-a4967812de7e.png)
![スクリーンショット 2025-02-07 10.34.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274361/178b6f14-b505-693c-93eb-8142d3aafffc.png)

コピーされる悪意あるコードは以下のようになっています。
![スクリーンショット 2025-02-07 11.23.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274361/55970555-7756-c732-7578-a3f7d3b3b97b.png)
## ClickFixで使われる悪意あるWebサイトの出現経路
攻撃者はさまざまな方法で誘導しようとします。
・受信したメールから誘導する
・改ざんされたWebサイトにアクセスする
・不正な広告からアクセスする
・etc.

特に下2つの方法は、不特定多数の人を誘導することができます。

### 改ざんされたWebサイトにアクセスする
正規のWebサイトを改ざんして、ClickFixに誘導させようとします。
下の画像は、ClearFakeがWebサイトに埋め込んだ改ざんコードです。
![スクリーンショット 2025-02-08 21.18.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274361/66fd29bd-d2b8-fd03-67bc-62cd68cef238.png)

### 不正な広告からアクセスする
検索結果などに表示された不正な広告からClickFixに誘導します。
特定の製品やサービスを騙った画面を表示します。

不正な広告を使った攻撃については、以下の記事が参考になります。

https://www.threatdown.com/blog/ongoing-webex-malvertising-drops-batloader/

https://www.malwarebytes.com/blog/news/2024/12/malicious-ad-distributes-socgholish-malware-to-kaiser-permanente-employees

## 実際の振る舞いについて
下のany.runの分析結果は、ClearFakeのClickFixの振る舞いがわかるものです。
偽のキャプチャ画面でコピーした悪意あるコードが実行されると、mshtaコマンドを使って不正サイト上に置かれたプログラムを実行しています。

https://app.any.run/tasks/7cfb5ff1-0058-48db-b572-b6ac8c54c742

## さいごに
正規のWebサイトを改ざんしたり、不正な広告から誘導したりと不特定多数の人を巻き込める手法を使っているため、ClickFixを知らないと引っかかってしまう可能性があります。
また、日本語で書かれているものも出回っています。
今後、日本の製品やサービスを騙ったものが出てくる可能性もあるため注意が必要です。
【Unity】親の Transform をリセットしつつ、子の位置・角度・拡縮を維持するコンポーネント

# 背景
モック制作で標準の立体を組み合わせたり拡縮・回転したりする機会がありました。
その過程で、子の配置を維持したまま親の Transform をリセットしたくなりました。
しかし、親の Transform をいじると子や孫の配置が変動してしまいます。
そこで、子の配置を維持したまま親の Transform をリセットする拡張を作りました。

### 備考
回転と拡縮が絡んだ状態でリセットすると歪んだ見た目になる恐れがあります。
より凝ったモックの地形を作る際は ProBuilder (無料)がおすすめです。


# コード

下記をプロジェクトに追加して GameObject を右クリックすると、メニューに```Reset Transform```が追加されます。

``` ResetTransformEditor.cs
#if UNITY_EDITOR
using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;

public class ResetTransformEditor
{
    [MenuItem("GameObject/Reset Transform/All", false, 1000)]
    public static void ResetTransform()
    {
        foreach (var go in Selection.gameObjects)
        {
            ResetProcess(go.transform, t =>
            {t.
                t.SetLocalPositionAndRotation(Vector3.zero, Quaternion.identity);
                t.localScale = Vector3.one;
            });
        }
    }
    [MenuItem("GameObject/Reset Transform/Position", false, 1000)]
    public static void ResetPosition()
    {
        foreach (var go in Selection.gameObjects)
        {
            ResetProcess(go.transform, t => t.localPosition = Vector3.zero);
        }
    }
    [MenuItem("GameObject/Reset Transform/Rotation", false, 1000)]
    public static void ResetRotation()
    {
        foreach (var go in Selection.gameObjects)
        {
            ResetProcess(go.transform, t => t.localRotation = Quaternion.identity);
        }
    }
    [MenuItem("GameObject/Reset Transform/Scale", false, 1000)]
    public static void ResetScale()
    {
        foreach (var go in Selection.gameObjects)
        {
            ResetProcess(go.transform, t => t.localScale = Vector3.one);
        }
    }

    private static void ResetProcess(Transform parent, Action<Transform> action)
    {
        var poses = new List<Vector3>();
        var rots = new List<Quaternion>();
        var scales = new List<Vector3>();

        for (int i = 0; i < parent.childCount; i++)
        {
            var t = parent.GetChild(i);
            poses.Add(t.position);
            rots.Add(t.rotation);
            scales.Add(new Vector3(
                t.localScale.x * parent.localScale.x,
                t.localScale.y * parent.localScale.y,
                t.localScale.z * parent.localScale.z));
        }

        action.Invoke(parent);

        for (int i = 0; i < parent.childCount; i++)
        {
            var t = parent.GetChild(i);
            t.SetPositionAndRotation(poses[i], rots[i]);
            t.localScale = scales[i];
        }
    }
}
#endif

```
データベースについて

# データベース関連について

## 1. データベース

データベースとは、**データを整理して保存し、簡単に取り出せるようにする仕組み**のこと。

:::note info
データベースを 本棚 に例えてみる。
本棚 → データベース（データを保存する場所）
本 → データ（例えば、ユーザー情報や商品リスト）
分類（ラベル） → データの整理方法（データベースの「テーブル」や「カラム」）
目次や検索機能 → データベースの検索機能（SQLなどを使ってデータを探す）
:::

## 2. DBMS

DBMS（データベース管理システム：Database Management System）とは、**データベースを管理し、データの追加・検索・更新・削除を簡単にできるようにするソフトウェア**のこと。

:::note info
DBMSを「レストラン」に例えてみる。
データベース（DB） → レストランの厨房
→ データを保存する場所（料理の材料を保管する場所）
DBMS → シェフ（料理人）
→ 必要な材料（データ）を取り出し、注文通りに料理を作る（データを加工・提供する）
SQL（データ操作の命令） → お客さんの注文 
→ 「ハンバーグをください！（ユーザー情報を取得してください）」とお願いする
:::

:::note info
DBMSの役割
データの保存・管理 🗂️
データを適切に保存し、壊れないように守る
データの検索・取得 🔍
必要なデータを素早く取り出す（例：特定のユーザー情報を取得）
データの追加・更新・削除 ✏️
新しいデータの追加や、不要なデータの削除を行う
アクセス管理（セキュリティ） 🔐
誰がデータにアクセスできるか管理（例：管理者だけがデータを編集できる）
同時アクセスの制御 ⚖️
たくさんのユーザーが同時にデータを使っても、問題が起きないようにする
:::

:::note info
代表的なDBMSの種類
リレーショナルデータベース管理システム（RDBMS）
➡ 「表（テーブル）」形式でデータを管理するDBMS

MySQL（Web開発でよく使われる）
PostgreSQL（高性能で企業向け）
SQLite（軽量で小規模向け）
SQL Server（Microsoft製のデータベース）
:::


## 3. RDBMS

RDBMS（リレーショナルデータベース管理システム：Relational Database Management System）とは、
**データを「表（テーブル）」の形で管理し、関係（リレーション）を持たせて整理するデータベース管理システム**のこと。

RDBMSは、複数の表（テーブル）を組み合わせてデータを整理し、簡単に検索・管理できるようにする仕組みを提供する。
例えば、「生徒」テーブルと「成績」テーブルを「生徒ID」で関連付ける。

:::note info
代表的なDBMSの種類
リレーショナルデータベース管理システム（RDBMS）
➡ 「表（テーブル）」形式でデータを管理するDBMS

MySQL（Web開発でよく使われる）
PostgreSQL（高性能で企業向け）
SQLite（軽量で小規模向け）
SQL Server（Microsoft製のデータベース）
:::

## 4. SQL

SQLとは、**データベースを操作するための言語（Structured Query Language）**のこと。

## 5. テーブル

テーブルとは、**データベースで情報を整理して保存するための「表（ひょう）」**のこと。

## 6. カラム

カラムとは、**表（テーブル）の列**のことで、データの種類を表す項目（縦）
「学年」や「クラス」など、どんな情報を保存するか決める

## 7. レコード

レコードとは、**表（テーブル）の行**のことで、実際のデータ（横）
「田中さん（1年A組）」や「佐藤さん（2年B組）」など、1行が1つのデータ

## 8. クエリ

クエリ（Query）とは、**データベースに対して「データを取得・追加・更新・削除するための指示（命令）」**のこと。
クエリは、SQLで書かれ、データを操作するために使われる。
rust result型について

http://ken25c28.fc2web.com/crenshu/renshu/r011.html

この問題をRustで解いていたときに
```
use std::io;

fn main() {
    let subjects: [&str; 3] = ["国語", "社会", "理科"];
    let mut scores: [i32; 3] = [0; 3];

    let mut input = String::new();
    for (i, subjects) in subjects.iter().enumerate() {
        print!("\n{}の点数=", subjects);
        io::stdin().read_line(&mut input);
        scores[i] = input.trim().parse::<i32>().expect("TypeError");
    }

    let sum: i32 = scores.iter().sum();
    let averave = sum as f64 / 3 as f64;

    println!("合計点は{}点です。\n平均点は{}点です。", sum, averave);
}
```

このようにぷろぐらむを組んでコンパイルしようとしたところ

```
warning: unused `Result` that must be used
  --> r011.rs:10:9
   |
10 |         io::stdin().read_line(&mut input);
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: this `Result` may be an `Err` variant, which should be handled
   = note: `#[warn(unused_must_use)]` on by default
help: use `let _ = ...` to ignore the resulting value
   |
10 |         let _ = io::stdin().read_line(&mut input);
   |         +++++++

warning: 1 warning emitted
```

こんな感じでWarningが出てきた。

調べたところ、
この警告は、`io::stdin().read_line(&mut input);` の戻り値 `Result<usize, std::io::Error>` を無視しているために発生しているとのこと

- `read_line` は `Result<usize, std::io::Error>` を返す関数であり、入力の読み取りが成功すれば `Ok(読み取ったバイト数)` を返し、失敗すれば `Err(エラー情報)` を返します。
- Rust では、Result 型を無視すると「エラーハンドリングを忘れている可能性がある」とみなされ、`#[warn(unused_must_use)]` により警告が発生します。

これを無視しないためには、`.expect()`や`.unwrap()`をもちいてエラーハンドリングを行うらしい

解決用のコードは以下に
```
io::stdin().read_line(&mut input).expect("読み取りに失敗しました");
io::stdin().read_line(&mut input).unwrap();
```
AWS CDK v2で擬似パラメータを使用する方法 in TypeScript

![001samune.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3984127/dc5fc510-a410-243b-f008-510e66f08703.png)

結論：**class ScopedAws**を使用します

# 概要
AWS CloudFormationで記述する際、擬似パラメータは必ずと言って良いほど使用するかと思います。
- 例. AWS::Region, AWS::AccountId

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/pseudo-parameter-reference.html

実はAWS CDKでも用意されています。
**aws-cdk-lib**(AWS CDKライブラリ)の**ScopedAws**クラスで定義されています。

https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.ScopedAws.html

:::note info
AWS CloudFormationのAWS::NoValue以外は定義されています
:::

# class ScopedAwsの使い方
使い方はドキュメントに記載がある通りです。
aws-cdk-libをインポートし、ScopedAwsクラスのインスタンスを作成することで使用できます。

```stack.ts
import * as cdk from "aws-cdk-lib";
/*
~
*/
const scopedAws = new cdk.ScopedAws(this);
```

# 実践
簡単ですが、IAMポリシーを作成してみます。

https://github.com/tyskJ/aws-cdk-pseudo-parameters

### stackファイル
デプロイするstackファイルを以下のように記述しました。
`resources`で呼び出しています。

```cdk-app-stack.ts
import * as cdk from "aws-cdk-lib";
import { Construct } from "constructs";
import * as iam from "aws-cdk-lib/aws-iam";

export class CdkAppStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // 擬似パラメータインスタンス作成
    const pseudo = new cdk.ScopedAws(this);

    // IAMポリシー作成
    new iam.ManagedPolicy(this, "policy", {
      managedPolicyName: "iam-policy",
      statements: [
        new iam.PolicyStatement({
          sid: "testPolicy",
          effect: iam.Effect.ALLOW,
          actions: ["ec2:StartInstances"],
          resources: [
            `arn:${pseudo.partition}:ec2:${pseudo.region}:${pseudo.accountId}:instance/*`,
          ],
        }),
      ],
    });
  }
}
```
### CFnテンプレート確認
`cdk synth --no-version-reporting --no-path-metadata`で出力されるCFnテンプレートがこちら。
AWS CloudFormationで使用できる擬似パラメータに変換されていることが確認できます。

```yaml
Resources:
  policyE16B4B70:
    Type: AWS::IAM::ManagedPolicy
    Properties:
      Description: ""
      ManagedPolicyName: iam-policy
      Path: /
      PolicyDocument:
      PolicyDocument:
        Statement:
          - Action: ec2:StartInstances
            Effect: Allow
            Resource:
              Fn::Join:
                - ""
                - - "arn:"
                  - Ref: AWS::Partition
                  - ":ec2:"
                  - Ref: AWS::Region
                  - ":"
                  - Ref: AWS::AccountId
                  - :instance/*
            Sid: testPolicy
        Version: "2012-10-17"
```

### デプロイして確認
`cdk deploy`で作成されたIAMポリシーがこちら。問題なく擬似パラメータが変換されているのが確認できます。

![画像1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3984127/cc8a45fc-421f-7bf2-6f60-ee211f566eac.png)

# まとめ
本記事では、擬似パラメータをAWS CDKで利用する方法についてまとめました。
本記事が誰かの役に立てば幸いです。

# 参考資料
### リファレンス
* [AWS CDK Reference Documentation 2.178.1](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.ScopedAws.html)
### ブログ
* ["cdk synth"で付与されるMetadataを取り除く](https://zenn.dev/watany/articles/d68316811c7112)
MQTTプロトコルについて

とある案件にて、HTTPでなくMQTTプロトコルを使ったデータのやり取りを実装することになりました。これを機に知識共有と備忘録を兼ねてMQTTについて紹介します。

# MQTTとは？
 **MQTT（Message Queuing Telemetry Transport）** は、1999年にIBM社とEurotech社により考案された軽量なメッセージプロトコルです。
MQTTは、限られたリソースを持つデバイスや、低帯域、高遅延、または信頼性の低いネットワーク環境向けに設計されています。そのため、機械同士が通信を介して情報をやり取りするM2M（Machine-to-Machine）や、家電や自動車など多種多様な「モノ」がインターネットにつながり、お互いに情報をやり取りするIoT（Internet of Things）を実現するのに適したプロトコルと言われています。

## パブリッシュ/サブスクライブモデル
MQTTは、 **パブリッシュ/サブスクライブ型** のメッセージングモデルを採用しています。
![MQTT.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3676048/7bf45947-c8a8-185e-ca54-e4f81c43d2ac.png)


+  **パブリッシャー** : メッセージの送信側
+  **サブスクライバー** : メッセージの受信側
+  **ブローカー** : MQTTサーバー。パブリッシャーからのメッセージを受信し、適切なサブスクライバーに配信する

パブリッシャーは、メッセージを特定のトピックにパブリッシュ(送信)します。サブスクライバーは、興味のあるトピックをサブスクライブ（受信）することで、そのトピックにパブリッシュされたメッセージを受け取れます。
このモデルの利点は、パブリッシャーとサブスクライバーが互いに相手を意識する必要がないことです。ブローカーがメッセージの配信を仲介するため、システムの複雑さを軽減し、スケーラビリティを向上させることができます。

# MQTTの特徴
+ 軽量
ヘッダーサイズが最小2バイトと小さく、ペイロードも軽量であるため、低帯域幅のネットワークや低消費電力のデバイスに適しています。
+ シンプル
プロトコルがシンプルで実装が容易であるため、様々なデバイスに組み込むことができます。
+ 非同期
パブリッシャーとサブスクライバーが互いの状態を意識する必要がないため、柔軟なシステム構築が可能になります。
+ 双方向通信
パブリッシャーとサブスクライバーは立場を入れ替えることができ、双方向の通信を実現できます。
+ メッセージの到達保証
 **QoS(Quality of Service)**  によって、メッセージの到達保証レベルを設定できます。
+ Will(遺言)機能
予期せぬ切断時に、ブローカーからサブスクライバーに特定のメッセージを送信できます。
# QoS（Quality of Service）
 **QoS（Quality of Service）** は、メッセージの到達保証レベルの定義です。以下の3つのレベルが定義されています。

+ QoS0 (At most once):
メッセージは最大1回配信されます。配信の保証はありません。
速度が最も速く、信頼性が低い
例：センサーデータの定期的な送信
+ QoS1 (At least once):
メッセージは最低1回配信されます。重複して配信される可能性があります。
信頼性が高い
例：重要なアラートメッセージの送信
+ QoS2 (Exactly once):
メッセージは正確に1回だけ配信されます。重複や損失はありません。
最も信頼性が高いが、速度が最も遅い
例：金融取引データの送信
パブリッシャーはどのQoSでメッセージを送信するか選択することができます。

# HTTPとの比較
HTTPは、クライアントがサーバーにリクエストを送信し、サーバーがそのリクエストに応答する、という同期型の通信プロトコルです。一方MQTTは、非同期型の通信プロトコルであり、パブリッシャーとサブスクライバーは互いに相手を意識することなくメッセージを送受信できます。

## MQTTのメリット
+ 軽量
HTTPと比較してはるかに軽量であるため、IoTデバイスのようなリソースの限られた環境に適しています。
+ 非同期通信
MQTTの非同期通信機能により、IoTデバイスのバッテリー寿命を延ばし、ネットワーク帯域幅を節約するのに役立ちます。
+ 多対多通信
1対多、多対多の通信をサポートしているため、IoTシステムの構築に適しています。
+ 不安定なネットワークへの対応
再接続機能やQoSによって、不安定なネットワーク環境でも信頼性の高い通信を実現できます。
# MQTTの利用例
MQTTは、様々な分野で利用されています。

+ 油田パイプライン監視
油田パイプラインに取り付けられたセンサーから衛星へのデータ送信
+ Facebook Messenger
メッセージの送受信
+ 自動車のIoT化
車両の状態監視、遠隔操作
+ 病院のペースメーカー監視
患者の心臓の状態を遠隔監視
+ 屋外の自動水やりシステム
センサーデータに基づいた自動水やり
+ 人工衛星
データ通信
# まとめ
今回はMQTTの概要について紹介しました。MQTTは、IoTに最適な軽量で効率的なメッセージングプロトコルです。今後ひはWindowsやLinux環境にブローカーを構築する方法なども機会があれば紹介していきたいと思います。
# 参考サイト
+ MQTTとは | かもめエンジニアリング
https://kfep.jp/solution/iot-mqtt/mqtt
+ MQTTとは？ IoT開発未経験者向けに概要と実用例をご紹介！
https://amg-solution.jp/blog/15787
+ MQTTとは？通信モデル・HTTPとの比較・利用メリット・実用例を紹介
https://www.kumikomi.jp/mqtt/
+ MQTTプロトコル解説：基礎知識とクイック・チュートリアル
https://www.emqx.com/ja/blog/the-easiest-guide-to-getting-started-with-mqtt
+ MQTTのQoSとは？QoSとは何かやレベル別ユースケースを紹介
https://www.kumikomi.jp/mqtt-qos/
きょうのgcc error

C言語記事へのコメント
https://qiita.com/kaizen_nagoya/items/89a9c709e7918e465d50

にあるWikiへのリンクのソースコードをコンパイルしてみた。

```
139b58:/tmp/gcc/mikecat_mixc# vi wiki.c
root@e69d75139b58:/tmp/gcc/mikecat_mixc# gcc -Wall -Wextra -O2 -o wiki wiki.c
wiki.c: In function 'main':
wiki.c:6:12: warning: missing terminating " character
    6 |   B(printf("#include <stdio.h>\nint main(int argc, char** argv)\n{\n#define B(x)
      |            ^
wiki.c:9:2: error: unterminated argument list invoking macro "B"
    9 | }
      |  ^
wiki.c:6:3: error: 'B' undeclared (first use in this function)
    6 |   B(printf("#include <stdio.h>\nint main(int argc, char** argv)\n{\n#define B(x)
      |   ^
wiki.c:6:3: note: each undeclared identifier is reported only once for each function it appears in
wiki.c:6:4: error: expected ';' at end of input
    6 |   B(printf("#include <stdio.h>\nint main(int argc, char** argv)\n{\n#define B(x)
      |    ^
      |    ;
......
wiki.c:6:3: error: expected declaration or statement at end of input
    6 |   B(printf("#include <stdio.h>\nint main(int argc, char** argv)\n{\n#define B(x)
      |   ^
wiki.c:2:14: warning: unused parameter 'argc' [-Wunused-parameter]
    2 | int main(int argc, char** argv)
      |          ~~~~^~~~
wiki.c:2:27: warning: unused parameter 'argv' [-Wunused-parameter]
    2 | int main(int argc, char** argv)
      |                    ~~~~~~~^~~~
root@e69d75139b58:/tmp/gcc/mikecat_mixc# ERRO[3849] error waiting for container:
```


```shell-session:docker
$ docker commit bb780993fd9a  kaizenjapan/gccqiita 
sha256:035251e835d9e8e30b4963e6298e77d5dfba53168c6cc45915a7ab7d51df40dc
$ docker push kaizenjapan/gccqiita
Using default tag: latest
The push refers to repository [docker.io/kaizenjapan/gccqiita]
198ab69cd830: Pushed 
3ed7ac3e2a38: Mounted from library/gcc 
0354c659d1f8: Mounted from library/gcc 
482ad84b6119: Mounted from library/gcc 
e8b7ad9c7816: Mounted from library/gcc 
d8a1e7648c7f: Mounted from library/gcc 
45e194afeef2: Mounted from library/gcc 
7bcfc560f59e: Mounted from library/gcc 
dc1054477fdd: Mounted from library/gcc 
latest: digest: sha256:6ea84eab3d7a2268116fea75081d406ffd9d0549e69faac7d692ada84c84a57a size: 2213
$ 
```
Chrome Extension Syncer 開発ストーリー：ある開発者の歩み

![顶部大图.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4006660/7e58d82a-d49b-101d-954f-156b879af1f5.png)


## インスピレーションの始まり

仕事用とプライベート用など、複数の Google アカウントを使い分ける開発者として、同じ Chrome 拡張機能を何度もインストールする手間にずっと悩んでいました。何度も繰り返すうちに、どの拡張機能が必要だったのかを忘れてしまうことも珍しくありません。

そこで思いついたのが、**複数の Chrome プロファイル間で拡張機能を手軽に同期できるツール**を作ること。そんな発想から生まれたのが、**Chrome Extension Syncer** です。

---

## この拡張機能は何をするのか

**Chrome Extension Syncer** は、シンプルながら強力なツールです。主な機能は以下のとおりです。

- **インストール済み拡張機能の一覧表示**  
- **拡張機能リストを JSON 形式でエクスポート**  
- **エクスポートしたリストを別のプロファイルでインポートし、現在の拡張機能と比較**  
- **欠けている拡張機能をワンクリックで簡単インストール**  
- **英語・中国語・日本語・韓国語など、多言語対応**  

アカウントやプロファイルを頻繁に切り替えたり、複数の人と拡張機能を共有したりする際に、とても役立ちます。

---

## 開発プロセス

このアイデアを実現するにあたり、次の技術を活用しました。

- **Plasmo Framework**：拡張機能を素早く開発するため  
- **React + TypeScript**：堅牢で拡張性のあるフロントエンド構築  
- **Material-UI**：使いやすく洗練されたインターフェース  
- **TailwindCSS**：柔軟かつメンテナンスしやすいデザイン実装  

最も重視したのは、ユーザーが迷わず使えることです。面倒な設定を極力なくし、エクスポートとインポートを数回のクリックだけで完結させることにこだわりました。

---

## 技術的な課題

### 課題 1: Chrome 拡張機能 API の制限

はじめは、完全自動で拡張機能をインストールする仕組みを考えていました。  
しかし、Chrome のセキュリティ方針により、拡張機能同士をバックグラウンドで勝手にインストールすることは認められていません。  
そこで、Chrome ウェブストアへのリンクを直接用意し、ワンクリックでインストールページを開けるようにしました。

### 課題 2: プロファイル間のデータ移行

拡張機能情報を別のプロファイルに引き継ぐには、単純なファイルコピーだけでは不十分でした。そこで、

- 拡張機能リストを汎用的な JSON 形式でエクスポート  
- アイコンやメタデータを含め、見やすく整理  
- 不足している拡張機能を簡単に識別できる比較機能を実装  

などの工夫を行いました。

### 課題 3: UI/UX デザイン

見やすく直感的で、かつ機能をしっかり提供するデザインを目指しました。

- サイドバーを中心に、必要な情報を一目で把握  
- インストール済み／未インストールの状態を視覚的に表示  
- インポート／エクスポートボタンをわかりやすく配置  
- ソーシャル共有機能を搭載し、多くの人に届けやすく  

---

## 誇りに思う成果

1. **ユーザー中心の設計**：余計な設定不要で、すぐ使い始められる  
2. **高いパフォーマンス**：拡張機能が多くてもスムーズに読み込み・処理  
3. **多言語対応**：世界中のユーザーが利用できる  
4. **クリーンなコード**：ベストプラクティスに基づく保守しやすい構造  

---

## 学んだこと

このプロジェクトを通じて、次のような大きな学びがありました。

1. **Chrome 拡張機能開発**  
   - Chrome 独自の拡張機能構造を理解  
   - API の活用方法とセキュリティ考慮事項

2. **モダン Web 開発**  
   - Plasmo Framework を用いた素早い開発  
   - TypeScript による安全性・予測可能性の確保  
   - React を活用した効率的な状態管理

3. **ユーザーエクスペリエンス**  
   - シンプルかつわかりやすいデザインの重要性  
   - ユーザーフィードバックがプロダクトを進化させる力  
   - 豊富な機能と使いやすさを両立する方法の模索  

---

## 今後のアップデート計画

今後、**Chrome Extension Syncer** をさらに便利にするため、以下の機能を検討中です。

1. **Extension Groups**：用途別やテーマ別に拡張機能をまとめて共有  
2. **クラウド同期**：拡張機能リストをクラウドに保存して簡単バックアップ  
3. **拡張機能のおすすめ機能**：ユーザーの利用傾向を基に人気拡張を提案  
4. **バックアップ＆リストア**：定期的に自動でバックアップして安心  
5. **拡張機能設定の同期**：拡張機能本体だけでなく、設定情報も同期する仕組みを検討  

---

## ぜひお試しください

実際にどのように動くのか気になる方は、[Chrome ウェブストア](https://chromewebstore.google.com/detail/bhnojmjkeoofbgecpijmpnepjdonaoak) で **Chrome Extension Syncer** をインストールしてみてください。使ってみた感想や、こういう機能があったらいいなといったアイデアがあれば、いつでもお寄せください！

---

もともとは個人的な悩みを解決するために始めたプロジェクトですが、いまでは多くの開発者や Chrome ユーザーの時間を大幅に節約できるツールに育ちました。少しでも興味を持っていただけたら、ぜひ周りの方々にもシェアしてください。皆さまが簡単に拡張機能を同期し、快適に作業を進められるようになることを願っています！
Dockerfileの記述方法

# Dockerfile記述方法
* `FROM <image>`: ビルドする際に拡張していくベースのイメージ
* `WORKDIR <path>`: イメージの中でコピーやコマンドを実行するためのパスを指定するための命令
* `COPY <host-path> <image-path>`: ホストからファイルをビルダーにコピーし、コンテナイメージの中に渡すための命令
* `RUN <command>`: ビルダーに明記したコマンドを実行させるための命令
* `ENV <name> <value>`: 実行するコンテナが使用する環境変数をセットするための命令
* `EXPOSE <port-number>`: イメージがexporseしたいポートをセットするための命令
* `USER <user or uid>`: この命令以降の命令のデフォルトユーザを指定するための命令
* `CMD ["<command>","<arg1>"]` : このイメージを使用するコンテナが実行するデフォルトのコマンドをセットするための命令

# RUN / CMDの違い
それぞれの特徴を以下に示します。
RUN : Dockerイメージのビルド時に実行される
CMD : コンテナ作成時に実行される

#　参考文献
[Writing a Dockerfile](https://docs.docker.com/get-started/docker-concepts/building-images/writing-a-dockerfile/)
[Dockerfile リファレンス](https://docs.docker.jp/engine/reference/builder.html#run)
[DockerfileにおけるCMDとRUNの挙動](https://qiita.com/subretu/items/31a387510f84daaa4c1c)
Qiitaのmarkdownで文字の大きさを変えたい

# はじめに

**Qiita** で記事を書く皆さん，文字を強調したいとき

- **太字にする**
- *斜体にする*
- <font color=red>カラーにする</font>

などの手段を取っていると思われますが，文字の大きさを変えることは難しいでしょう。**Qiita** では **HTML** タグである `<font size=*>` やスタイルシート指定 `style="font-size:*"` が使えないからです。

<h1><font color=red>HTML タグを用いた場合</font></h1>
<h2><font color=red>HTML タグを用いた場合</font></h2>
<h3><font color=red>HTML タグを用いた場合</font></h3>
<h4><font color=red>HTML タグを用いた場合</font></h4>
<h5><font color=red>HTML タグを用いた場合</font></h5>
<h6><font color=red>HTML タグを用いた場合</font></h6>

**markdown** の基本文法である見出し記号 `#` もしくは `<h1>` ～ `<h6>` までのタグを用いると文字列の強調（大きさ，太字）は可能ですが，残念ながら見出しになってしまうのです。たとえば上記の文字列は見出しになっていることが分かります。`<h1>` ～ `<h2>` までは下線も引かれます。

```:HTML タグを用いた場合
<h1><font color=red>HTML タグを用いた場合</font></h1>
<h2><font color=red>HTML タグを用いた場合</font></h2>
<h3><font color=red>HTML タグを用いた場合</font></h3>
<h4><font color=red>HTML タグを用いた場合</font></h4>
<h5><font color=red>HTML タグを用いた場合</font></h5>
<h6><font color=red>HTML タグを用いた場合</font></h6>
```

# MathJax を用いた場合

**MathJax** を用いる方法があります。筆者の確認したところ以下の５段階で大きさを設定できるようです。

$\color{red}{\huge  \textsf{MathJax を用いた場合}}$
$\color{red}{\large \textsf{MathJax を用いた場合}}$
$\color{red}{       \textsf{MathJax を用いた場合}}$
$\color{red}{\small \textsf{MathJax を用いた場合}}$
$\color{red}{\tiny  \textsf{MathJax を用いた場合}}$

```:MathJax を用いた場合
$\color{red}{\huge  \textsf{MathJax を用いた場合}}$
$\color{red}{\large \textsf{MathJax を用いた場合}}$
$\color{red}{       \textsf{MathJax を用いた場合}}$
$\color{red}{\small \textsf{MathJax を用いた場合}}$
$\color{red}{\tiny  \textsf{MathJax を用いた場合}}$
```

**MathJax** は字体（フォント）も変えることができます。

$\color{red}{\textsf{MathJax を用いた場合}}$
$\color{red}{\textrm{MathJax を用いた場合}}$
$\color{red}{\textbf{MathJax を用いた場合}}$
$\color{red}{\texttt{MathJax を用いた場合}}$

```:MaxJax を用いた場合その２
$\color{red}{\textsf{MathJax を用いた場合}}$
$\color{red}{\textrm{MathJax を用いた場合}}$
$\color{red}{\textbf{MathJax を用いた場合}}$
$\color{red}{\texttt{MathJax を用いた場合}}$
```

# PlantUML を用いた場合

**PlantUML** を用いる方法もあります。コチラは文字の大きさやフォントなど自由に設定できます。ただし，画像として貼り付けられているため，テキストをコピー＆ペーストできないうえ，周囲にはグレーのボーダーラインが入ってしまっているのが残念なところです。

```plantuml
<style>
root {
  padding 0
  margin 0
}
title {
  horizontalAlignment left
  fontStyle normal
  fontColor red
}
</style>
title
<size:48>PlantUML を用いた場合</size>
<size:36>PlantUML を用いた場合</size>
<size:24>PlantUML を用いた場合</size>
<size:18>PlantUML を用いた場合</size>
<size:12>PlantUML を用いた場合</size>
end title
```

````:PlantUML を用いた場合
```plantuml
<style>
root {
  padding 0
  margin 0
}
title {
  horizontalAlignment left
  fontStyle normal
  fontColor red
}
</style>
title
<size:48>PlantUML を用いた場合</size>
<size:36>PlantUML を用いた場合</size>
<size:24>PlantUML を用いた場合</size>
<size:18>PlantUML を用いた場合</size>
<size:12>PlantUML を用いた場合</size>
end title
```
````

# Mermaid を用いた場合

**Qiita** でサポートしている二大作図言語のもう一つ **Mermaid** を使う方法です。コチラは図の周囲に不自然なボーダーラインが入らないですし，テキストのコピー＆ペーストも可能です。ただし，余白の大きさを変更できないうえ，タイトル文字列の大きさも変えられないのが残念なところです。※変更方法がまだ見つかっていません。

```mermaid
---
title: Mermaid を用いた場合
---
%%{init{'themeVariables':{'textColor': 'red'}}}%%
graph LR
```

````:Mermaid を用いた場合
```mermaid
---
title: Mermaid を用いた場合
---
%%{init{'themeVariables':{'textColor': 'red'}}}%%
graph LR
```
````

# まとめ

本件に対しては引き続き調査中です。進展があり次第，報告したいと思います。
メモリスワップ

### 1. スワップの追加

スワップファイルの作成と有効化
```bash
sudo fallocate -l 1G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
```

スワップファイルを起動時に自動で有効化
```
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
```

### 2. 使用量の監視

ディスク使用量の確認
```bash
sudo df -h
```

特定ディレクトリの使用量確認
```bash
sudo du -sh /var/*
```

### 3. スワップファイルの無効化

スワップファイルの無効化

```bash
sudo swapoff /swapfile
```

/etc/fstab ファイルからスワップの設定を削除

```bash
sudo nano /etc/fstab
```

次の行を探し削除

```bash
/swapfile none swap sw 0 0
```

変更を保存し、エディタを終了

### 4. スワップファイルの削除
スワップファイルを削除して、ディスクスペースを確保

```bash
sudo rm /swapfile
```

スワップファイルが正常に削除されたことを確認
```bash
sudo swapon --show
free -h
```
WSL1でUbuntu24.04を使うためのTips

WSL1を使い続けていると、WSL2しか見ていない人達によってWSL1が見捨てられているのを感じていますが、WSL1はWSL1でいいところがあるのです。
[WSL1が本家のWSLであってWSL2はおもてたんと違う! #WSL - Qiita](https://qiita.com/yugo-yamamoto/items/ac31bbd00f6b88e05793)

Better CygwinとしてWSL1を使っているのでこれからもWSL1を使いたいのですが、Ubuntu 24.04をうまく動かせないことがあるため、その知見をためておきます。

大抵systemdが悪いです。

## systemdの更新を止める
WSL1でUbuntu24.04を使うと、apt upgradeや他のパッケージインストール時にsystemd周辺でエラーが出る。(そもそもWSL1でsystemdは使えないのに)

```
Errors were encountered while processing:
 systemd
 systemd-timesyncd
 udev
 libpam-systemd:amd64
 systemd-resolved
 systemd-sysv
 ubuntu-minimal
 ubuntu-wsl
 libnss-systemd:amd64
E: Sub-process /usr/bin/dpkg returned an error code (1)
```

WSL1はsystemdをサポートしていないので当然ではあるが、これでは他のパッケージを入れられない。これはapt-mark holdで更新を止めることで回避できる。

```
sudo apt-mark hold systemd
```
```
sudo apt-mark hold systemd-dev
```

```
mikuta0407@S12Pro:~$ cat /etc/os-release
PRETTY_NAME="Ubuntu 24.04.1 LTS"
NAME="Ubuntu"
VERSION_ID="24.04"
VERSION="24.04.1 LTS (Noble Numbat)"
VERSION_CODENAME=noble
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
UBUNTU_CODENAME=noble
LOGO=ubuntu-logo
mikuta0407@S12Pro:~$ uname -a
Linux S12Pro 4.4.0-22621-Microsoft #4391-Microsoft Fri Jan 01 08:00:00 PST 2016 x86_64 x86_64 x86_64 GNU/Linux
mikuta0407@S12Pro:~$ sudo apt update
Hit:1 http://security.ubuntu.com/ubuntu noble-security InRelease
Hit:2 http://archive.ubuntu.com/ubuntu noble InRelease
Hit:3 http://archive.ubuntu.com/ubuntu noble-updates InRelease
Hit:4 http://archive.ubuntu.com/ubuntu noble-backports InRelease
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
All packages are up to date.
mikuta0407@S12Pro:~$
```
参考: [windows subsystem for linux - Upgrade of a freshly installed WSL1 Ubuntu 24.04 fails - Super User](https://superuser.com/questions/1863713/upgrade-of-a-freshly-installed-wsl1-ubuntu-24-04-fails)

## systemd-sysusersを偽装してエラーを回避

systemdが動かないことでsystemd-sysusersがうまく動かず、こんなエラーが出てくることがある。

```
Failed to take /etc/passwd lock: Invalid argument
dpkg: error processing package systemd (--configure):
 installed systemd package post-installation script subprocess returned error exit status 1
Errors were encountered while processing:
 systemd
E: Sub-process /usr/bin/dpkg returned an error code (1)
```

これはsystemd-sysusersをechoのシンボリックリンクにすることで回避できる。

```
cd /bin && mv -f systemd-sysusers{,.org} && ln -s echo systemd-sysusers && cd -
```

[Updating `systemd` in WSL1 Kali Linux fails with `Failed to take /etc/passwd lock: Invalid argument` · Issue #10397 · microsoft/WSL](https://github.com/microsoft/WSL/issues/10397#issuecomment-1780132430)
ransacker を利用したカスタム検索機能の実装

# ransacker を利用したカスタム検索機能の実装

この記事では、Rails アプリケーションにおいて、**テーブルに直接存在しない計算結果や集計値** を検索条件として利用する方法をご紹介します。具体的には、`Book` モデルに関連付けられた `Post` の件数を基に検索を行う例を取り上げます。

---

## はじめに

Rails で検索機能を実装する際、`ransack`という Gem を利用しました。

そこで、テーブルのカラムにない値で検索をする必要があり、それを達成するためにはransackerを利用すればできるということを学びました。学んだ内容を記事にしたいと思います。

ちなみに、ransackで検索機能をつくるのは以下の記事を参考にしました。

### 参考記事

https://zenn.dev/sudoukky/articles/4d4550bdc677be

https://qiita.com/mmaumtjgj/items/8731a70b3f328770867c

---

## 環境

- **Ruby:** 3.2.4
- **Ruby on Rails:** 7.1.2

---

## ransacker とは？

**ransacker の目的**

Ransack は Rails アプリケーションに柔軟な検索機能を提供する Gem です。しかし、標準状態ではテーブルに存在するカラムのみが検索対象となります。

そこで、`ransacker` を利用することで、以下のようなケースに対応可能です。

- 計算結果や集計値を検索条件に含めたい場合
- テーブルのカラム以外のデータを検索に利用したい場合

この記事では、`Book` に関連する `Post` の件数（投稿数）を検索対象とする例を取り上げます。

---

## データベースの構成

今回のサンプルでは、`Book` と `Post` が **1対多 (has_many/belongs_to)** の関係になっています。

### `app/models/book.rb`

```ruby
class Book < ApplicationRecord
  has_many :posts, dependent: :destroy
end
```

### `app/models/post.rb`

```ruby
class Post < ApplicationRecord
  belongs_to :book
end
```

---

## カスタム検索条件の実装

モデル内に `ransacker` メソッドを定義することで、仮想的な属性を検索条件として追加できます。以下のコード例では、`posts_count` という仮想属性を定義し、`Book` に紐付く `Post` の件数を取得する SQL サブクエリを利用しています。

```ruby
# app/models/book.rb

class Book < ApplicationRecord
  has_many :posts, dependent: :destroy

  ransacker :posts_count do
    Arel.sql('(
      SELECT COUNT(posts.id)
      FROM posts
      WHERE posts.book_id = books.id
    )')
  end
end
```

この定義により、ransack を使った検索時に `posts_count` を条件として指定できるようになります。たとえば、投稿数が特定の数以上の書籍を抽出するなどの検索が可能です。

---

## おわりに

今回の実装例では、SQL のサブクエリを利用して仮想属性を定義しましたが、データ量が増加するとパフォーマンス面で課題が出る可能性があります。

そのため、将来的に投稿数での検索を多用する場合は、**`posts_count` カラムを用意し、投稿作成や削除時にカウントを更新する** などの対応が良さそうです。
AWSの基礎知識

## はじめに
初心者がAWSの基礎知識を備忘を含め書きます
間違いあればご教示いただきたく

## AWSとは
「Amazon Web Services」はAmazonが提供するクラウドコンピューティングサービスの総称です。
インターネット経由でサーバー、データベース、ストレージ、ネットワーク、AIなどのさまざまな機能を利用できます。
そのため、物理的なサーバーを購入・管理せずに、必要なリソースをレンタルしてアプリやWebサイトを動かせる のが特徴です。
また、クラウドサービスとは、自分のPCにデータやソフトウェアを保存せず、インターネット経由で様々な機能を利用できる仕組みのことを指します。

## VPC
「Virtual Private Cloud」の略
AWS内でVPCというプライベートな領域を作り、その中で自由にネットワークを作成できます

VPCを作成する際には、まずIPアドレスの範囲（CIDRブロック）を指定します。
VPC内では、異なるネットワークを「サブネット」 として分割できます。

サブネットを分割する理由の一つとして、セキュリティ対策があり、
**パブリックサブネット（インターネットからアクセスできるサーバーを配置）
プライベートサブネット（データベースなど外部に公開しないサーバーを配置）**
のように使い分けることが一般的です。

<img src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3842150/edfb1307-9327-743c-3571-f661ac9e78df.png" width = 50% >


## EC2
「Elastic Compute Cloud」の略
EC2では仮想のコンピュータのスペック(CPUやディスク容量など)を指定しサーバを構築します
作成した各サーバの個体をインスタンスと呼びます
インスタンスの作成の流れは以下になります
### リージョンの選択
AWSマネジメントコンソールにログインし、インスタンスを配置したいリージョンを選びます。
リージョンとは、AWSのデータセンターがある地理的なエリアのことです。
リージョン内には **「アベイラビリティゾーン（AZ）」** と呼ばれる複数のデータセンターがあり、
冗長構成が整えられています。
このため、特定のゾーンで障害が発生しても、別のゾーンに切り替えてシステムを継続できます。

### AMIの選択
インスタンスにインストールするオペレーティングシステムやソフトウェアのテンプレートであるAMIを選択します。
自分は現時点(2025/2/9)で最新のAmazon Linux 2023を選択しました

### インスタンスタイプの選択
インスタンスタイプとは仮想マシンのスペックのことです(CPU、メモリ、ストレージ、ネットワーク性能など)
用途や予算に応じて適切なタイプを選択してください。

## Route53
Route 53 は、AWSが提供するフルマネージド型のDNSサービス です。
主な役割は、 **「ドメイン名（google.com）をIPアドレス（173.194.222.106）に変換する」** ことです。

また、Route 53 には以下のような機能もあります

ドメインの取得・管理（AWS上でドメインを購入可能）
トラフィックルーティング（負荷分散やリージョンごとの最適なサーバーへの振り分け）
ヘルスチェック（サーバーの死活監視）
「フルマネージド型」とは、サーバーのセットアップやソフトウェアのインストールなどをユーザーが行う必要がなく、管理に専念できるサービスを指します。

<img src = https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3842150/391b5020-cfd0-ea87-ae7e-8140e4f8e146.png width = 50%>


## RDS
「Relational Database Service」の略
RDSはフルマネージド型のリレーショナルデータベースサービスです。
MySQLやPostgreSQLなどのDBが使用できデータのバックアップ・セキュリティ対策も自動でできます 
<img src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3842150/98aaca64-9a2d-92b6-a4a6-ed17e4754282.png" width = 50%>


## ELB
「Elastic Load Blancing」の略
AWSの負荷分散（ロードバランサー）サービスです。
Webサイトやアプリケーションに多くのアクセスが集中すると、1台のサーバーでは処理しきれずパフォーマンスが低下する可能性があります。

ELBを使うと、複数のEC2サーバーにアクセスを自動で分散し、サイトの負荷を軽減できます。
また、1台のサーバーがダウンしても、自動的に他のサーバーに振り分けることで、システムの高可用性を確保できます。
<img src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3842150/bbb81638-521a-4edb-2117-333bd2479368.png" width = 50%>

## 最後に
AWSは覚えることがたくさんありますが、実際に手を動かして実装するのが一番理解しやすいと思いました
自分もまだまだですが、繰り返し学習していこうと思います
アジャイル検定Lv.1試験の勉強メモ

# はじめに
アジャイル検定Lv.1を受験しました。
その試験直前にまとめた内容を共有する記事で、『アジャイル検定公式テキスト』の内容メモです。

受験までにしたことや結果は以下の別記事で紹介しています。

https://qiita.com/e_e99/items/d4adc7d0b675253129e4

# プロジェクト管理
アジャイルチームは以下の3つから成る。
1. 開発チーム
1. プロダクトオーナー
1. チームリーダー

チームの規約を作る。
顧客の関係者やプロダクトオーナーと開発チームが同一の拠点で作業し気軽に会話できる環境が理想。

### 開発チーム
計画、管理、実行、コミュニケーションを開発チーム自身で行う。
### プロダクトオーナー
開発する製品の最終責任者。
プロジェクトのビジョンや製品の提供する価値をチームに伝える。
ストーリーの管理に責任を持つ。

### チームリーダー
アジャイル開発に関するコーチングを行う。
外部の妨害からチームを守る。

## プロジェクト全体計画
ストーリーの洗い出しと優先順位付け。
プロジェクトの最初に、イテレーションの長さと実施する回数を計画。
どのイテレーションでどのストーリーを実装、リリースするかの計画立案。

## イテレーションの流れ
イテレーションは、各開発サイクルのことで、数週間から数ヶ月程度。
イテレーション開始前に、優先順位に基づき次のイテレーションでの開発範囲を決定。

イテレーション計画で対象のストーリーをタスクに分解し、そのイテレーションで実施可能な範囲にスコープを変更。

イテレーションの終わりにはチームの反省会（レトロスペクティブ）を行い、技術的な問題やプロセスに関することについても話し合う。

イテレーションのレビュー会議は開発チーム主催で、利害関係者に成果物のデモンストレーション等を行う。

イテレーションの期間中はチームでの問題や課題はチーム内で解決するのが基本。

## チームの振り返り
アジャイルチームの振り返りは、毎週日時を決めて実施するのが一般的。

## 各種手法
### ペアプログラミング
- ドライバー
タイピングする人。基本的にはナビゲータの指示通りにコードを書き、疑問点がある場合にはディスカッション。
- ナビゲーター
コード設計をドライバーに指示。

役割は一定時間ごと、ペアは日ごと程度で変えると良い。
休憩を定期的に取ることをルール化することが必要。

### リファクタリング
開発効率の向上、提供までの時間が短くなるユーザーメリットもある。
ソースコードに手を加えるタイミングに少しずつ行う。

### 常時結合（CI: Continuous Integration）
1. コミット
1. 自動ビルド
1. 自動テスト
1. フィードバックからバグを修正

の流れが良い。
問題の早期発見や素早いフィードバックがメリットである。

### テスト駆動開発
1. テストコードを書く
1. テストを通るように機能を実装
1. リファクタリング

各テストコードは独立であり、最初はコンパイルエラーとなる。

# まとめ
アジャイル開発とはよく聞く開発手法ですが、ウォーターフローとの比較で用いられる言葉であり、実際の開発ではその中のスクラム開発とかを採用しているようだと思いました。
【備忘録】Anaconda環境移植

## 仮想環境情報をファイルに出力して保存
```
activate base_env
```
```
cd Desktop
```
```
conda env export > base_env.yml
```
## 保存した仮想環境情報から新たな環境構築
```
conda env create -n new_env -f base_env.yml
```
\
※仮想環境情報をテキストで出力する方法
```
conda list --export > base_env.txt
conda list --export > new_env.txt
```
Laravel 11でメインのblade.phpファイル名を変更する

## ルート設定の変更
ファイル: routes/web.php
デフォルトではwelcome.blade.phpが表示されるように設定されているので、任意のファイル名に変更します。今回はapp.blade.phpとします。
具体的には`return view('welcome');`を`return view('app');`に変更します。

**web.php**
```
use Illuminate\Support\Facades\Route;

Route::get('/', function () {
    return view('app');
});
```
## welcome.blade.phpを削除または名称変更
welcome.blade.phpを削除または名称変更してapp.blade.phpを作成します。ファイル内の記述については本章では省略します。

## キャッシュのクリア
**bash**
```
php artisan config:clear
php artisan view:clear
php artisan cache:clear
```
## サーバーの再起度
必要に応じてLaravelとViteの開発サーバーを再起動します。

### Laravelサーバー再起動
**bash**
```
php artisan serve
```
### Viteサーバー再起動
**bash**
```
npm run dev
```
全シートをA1セル、表示倍率100%、スクロール位置を左上に変更するマクロ

個人用マクロかアドインに追加することで利用可能。
追加方法は別途投稿したい。

```
'全シートをA1セル、表示倍率100%、スクロール位置を左上に変更する
Private Sub subSetA1()
    Dim ws As Worksheet
  
    '各シート、A1セル、表示倍率100%、スクロール位置を左上に変更
    For Each ws In ActiveWorkbook.Worksheets
        ws.Activate
        ws.Cells(1, 1).Select
        ActiveWindow.Zoom = 100
        ActiveWindow.ScrollColumn = 1
        ActiveWindow.ScrollRow = 1
    Next
    
    '先頭シートを選択
    ActiveWorkbook.Worksheets(1).Activate
    
End Sub
```