OmniAICreator/Qiita-1.07M huggingface dataset:
Gitlabって便利じゃね？

# Gitlabについて

### なぜ書こうと思ったか
Gitlabを会社で使うことがあって、使っていたら結構便利じゃね？ってなったが、
誰もあまり教えてくれないので宣伝を兼ねて作成。
~~Gitlabさん。宣伝費をくれてもいいのよ~~

### Gitlabってそもそも何？
Gitlabは主に企業などで大規模開発を行う際に利用するものです。
コマンドや操作感はほとんど、Githubと同じです。
では何が違うのかですが、Gitlabの最大の特徴は主に2つあります。
* リポジトリの管理を階層形式で管理できる
* アクセス権の管理が非常に楽

１つずつ解説していきます。


※ビルドなどでも便利そうな機能がありますが全容把握してないので、それは割愛。

#### リポジトリの階層管理

リポジトリをフォルダやファイルと同じように階層構造で以下のように管理ができます。

```bash
.
├── your_groupA/
│   ├── sub_groupA1/
│   │   ├── your_repositoryA1
│   │   └── your_repositoryA2
│   └── sub_groupA2/
│       ├── your_repositoryA3
│       └── your_repositoryA4
└── your_groupB/
    ├── sub_groupB1/
    │   ├── your_repositoryB1
    │   └── your_repositoryB2
    └── sub_groupB2/
        ├── your_repositoryB3
        └── your_repositoryB4
```
正直これだけは具体的なイメージがわかないと思います。
以下が実際のGitlabの画像です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4037629/9d55e774-a13b-4f68-b2c2-2297b92ebd2f.png)

ここでいう「trade」などがyour_groupAに該当します。
例として「仮想通貨データ取得」のグループに移動してみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4037629/d666dd4e-5742-4f71-8737-b0752e3c2370.png)

ここではリポジトリの作成やサブグループの作成が可能です。
今はリポジトリだけ作成している状況です。
右上の新しいサブグループや、新しいプロジェクトでリポジトリやサブグループの作成が可能です。
結構管理が容易じゃないですか？
Githubあるあるリポジトリを乱雑に作りまくってどれがどれだかわからなくなるという事象がこれで解決できるので、かなり便利だと思います。

#### アクセス権の管理が非常に楽
これは大規模開発であればあるほど起きる問題だと思いますが、
* リポジトリへのアクセス権をいちいち付与するのはだるい
* アクセスできても閲覧権だけにしたい
など様々要望があるかと思います。
そういう際に、ここではグループごと（サブグループを含む）にコントリビューターのように招待でき、そこでアクセス権の調整が可能です。
Role系の管理画面は以下のようになっていますので早速見てみましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4037629/114d32cb-834f-437c-bac7-77f60da75e46.png)

※アカウントとソースはちょっとばれるとだるい情報が含まれていたので隠させてもらいました。ソースは誰がこの人を招待したとかが書いています。

ロールではどのような権限の付与ができるかですが、
以下ロールをグループ単位で付与が可能です。

* Guest (This role applies to private and internal projects only.)
* Planner
* Reporter
* Developer
* Maintainer
* Owner
* Minimal Access (available for the top-level group only)
※[出典：公式ガイド](https://docs.gitlab.com/user/permissions/)

なにがなにやらという感じですが以下が権限でできることの表になります。

|Action|Guest|Planner|Reporter|Developer|Maintainer|Owner|
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
|マージ履歴などの監視|✓|✓|✓|✓|✓|✓|	
|マージ履歴などのダッシュボード監視|✓|✓|✓|✓|✓|✓|	
|イシューの閲覧|✓|✓|✓|✓|✓|✓|	
|コントリビューターの状況監視|✓|✓|✓|✓|✓|✓|
|View value stream analytics|✓|✓|✓|✓|✓|✓|
|マージリクエストの詳細監視| | |✓|✓|✓|✓|
|DevOpsの導入状況| | |✓|✓|✓|✓|
|メトリクスのダッシュボード監視| | |✓|✓|✓|✓|
|リポジトリやグループの作成権限||||✓|✓|✓|

このようにアクセス権をグループごとの細かく設定できます。
また有効期限を設定できるため、派遣さんなど有期契約の方でも管理が容易です。
これで大規模開発を行う際に、Aさんはバックエンド開発なので、バックエンドグループにはDeveloperでアクセス権を与えてあげようとか、BさんはPMOなので、全部のリポジトリにアクセス権を与えるけど、作成権はあたえたくないので、Reporter権限で全部のリポジトリにアクセス権を与えようなど…自由自在です。
少人数であってもチームを組んで開発を行うならあると結構役に立つと思います。
少なからず僕はアクセス権を毎度毎度付与して友達と開発するのは正直かったるいなと思うので結構便利です。

### まとめ
リポジトリを階層管理しつつ、それをもとにアクセス権を与えることで簡単に大規模開発のリポジトリを管理できてめっちゃ便利だよねっていう代物です。
ぜひ会社や個人開発で活用してみてください。
【TypeScript初心者メモ】type型

# typeとは
typeは、型に名前（別名）をつける仕組みです。
基本構文：`type 型名 = 型定義;`

# 具体例
1．基本型のエイリアス
```
// UserId は number 型の別名。
type UserId = number;
// 意味づけを明確にできる（例：IDとして使う数値だとわかる）
const id: UserId = 123;
```
2．オブジェクト型のエイリアス
```
// よく使う構造に名前をつけて再利用できる
type User = {
  id: number;
  name: string;
  isActive: boolean;
};
const user1: User = {
  id: 1,
  name: "Taro",
  isActive: true
};
```
3．関数型のエイリアス
```
// 関数の型を表現して再利用
type Greet = (name: string) => string;
const greetUser: Greet = (name) => `Hello, ${name}`;
```
4．配列・タプルの型エイリアス
```
type NameList = string[];
const names: NameList = ["Taro", "Hanako"];
```

```
type Point = [number, number];
const pos: Point = [10, 20];
```
Pythonのクラスメソッドについて勉強してみた

# 概要
Java, Python等のオブジェクト指向言語を扱っていると避けて通れないのがクラスという概念  
今回はクラスメソッドについてまとめていこうと思います  

というのは表向きな理由で本当はGoFのデザインパターンを勉強するにあたり、ここらへんを理解してないと無理だなと思い出してきたので勉強を始めました。。。
# そもそもクラスメソッドとは?
- クラス全体に関わる操作を実施する: クラス変数やクラスから新しいインスタンスを生成するような操作を使用する際に使用される
- クラス自体に紐づくメソッドであり、インスタンスを生成せずにメソッド名で直接呼び出すことができる  

Pythonでは以下のように実装される  
```
# クラスの内容
Class SampleClass:
    class_variable = "hoge" # クラス変数

    def __init__(self, name):
        self.name = name # インスタンス変数

    @classmethod # デコレータする
    def sample_function(cls, arg1: str, arg2: int): # 第一引数はclsにする
        return cls.class_variable

# クラスメソッドの呼び出し
SampleClass.sample_function('sample', 123) # インスタンス化せずに呼び出し可能
```
  
## 第一引数のclsって何?
その**メソッドがクラスに属していることを表すため**に設定するようです  
clsはそのクラス自身を表して、clsを介してクラス変数やクラスメソッドにアクセスできるようです  
class固有の変数や関数にアクセスするための目印的なものだと考えてもいいかなと思います  
*第一引数のclsは慣習的になっているようで、それ以外でも大丈夫なようです  

# インスタンスメソッドとの違いは?
インスタンスメソッドはインスタンス自体に紐づくのため、以下のような違いがあるようです  
  
| 項目名 | クラスメソッド | インスタンスメソッド |
| :-- | :-- | :-- |
| 呼び出し方 | クラス名.メソッド名 | インスタンス名.メソッド名 | 
| 第一引数 |  cls(クラス自身) | self(インスタンス自身) |
| 参照できるもの | クラス変数 | インスタンス変数, クラス変数 |

# 実際の使用方法
## 使用例
- クラス変数の変更: クラス全体に関わるような変数の値の変更
- ファクトリーメソッド
- クラスの情報取得: クラス名やモジュール名の崇徳

## コード例
### クラス全体に関わる部分
```
class Takoyaki:
    """たこ焼き屋のクラス
    """
    shop_type: str = "たこ焼き屋"

    def __init__(self, name: str, tel_number: str):
        self.name = name
        self.tel_number = tel_number

    @classmethod
    def show_shop_type(cls):
        print(cls.shop_type)
    
    @classmethod
    def cash(cls, cart: list):
        """会計メソッド
        会計処理は店に問わず統一なのでclassmethodにしている
        cart: [{'8個セット': {'price': 800, 'count': 2}}, {'12個セット': {'price': 1000, 'count': 1}}]
        """
        result = {}
        for item, cart_info in cart.items():
            total_price = cart_info['price'] * cart_info['count']
            result[item] = total_price
        
        return result

    def show_shop_info(self):
        print({'店名': self.name, '電話番号': self.tel_number})

if __name__ == '__main__':
    Takoyaki_A = Takoyaki('hoge', '00-0000-0000')
    Takoyaki_B = Takoyaki('huga', '11-2222-3333')

    Takoyaki_A.show_shop_type()
    Takoyaki_B.show_shop_type()
    Takoyaki_A.show_shop_info()
    Takoyaki_B.show_shop_info()

```
### 環境変数の参照
```
class EvnData:
    """環境変数を格納するクラス
    """
    __DB_TYPE = "MYSQL"
    __DB_ADDRESS = "127.0.0.1"
    __DB_PASS = "hoge"

    @classmethod
    def get_db_info(cls):
        return {"DB_TYPE": cls.__DB_TYPE, "DB_ADDRESS": cls.__DB_ADDRESS, "DB_PASS": cls.__DB_PASS}

if __name__ == '__main__':
    print(EvnData.get_db_info())
```

# 参考サイト
- [Python公式サイト](https://docs.python.org/ja/3.8/library/functions.html#classmethod)
- [Python classmethodとstaticmethodを使う意味を考える](https://it-for-pharma.com/python-classmethod%E3%81%A8staticmethod%E3%82%92%E4%BD%BF%E3%81%86%E6%84%8F%E5%91%B3%E3%82%92%E8%80%83%E3%81%88%E3%82%8B)
【React初心者メモ】エイリアス（:）

# エイリアスとは
エイリアスとは、変数名やプロパティ名を他の名前で扱う構文です。

# 使われる場面
1．オブジェクトの分割代入でエイリアスを使う
```
const user = {
  id: 1,
  username: 'hana',
  age: 20
};
// username → name に別名をつけて使う
const { username: name } = user;
console.log(name); // 'hana'
```
2．関数の引数でエイリアスを使う
```
const printUser = ({ username: name }: { username: string }) => {
  console.log(name);
};
printUser({ username: 'taro' }); // 'taro'
```
3．型でエイリアスを使う
```
type UserId = number;
const getUser = (id: UserId): void => {
  console.log("ID:", id);
};
```
Windowsでエクスプローラが反応しなくなったら


# 何かエクスプローラが固まった

という場合、以下で治ることが多いです。
＃ただ、デスクトップ含めて一瞬暗くなり、開いていたエクスプローラ消えるので、
　驚かないように、作業の切りの良いところで試しましょう。

```
Ctrl＋Shift＋Esc　→　「プロセス」タブ　→　アプリ > エクスプローラーを右クリック > 再起動(R)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3562068/ebdd268b-e2af-4b31-b01a-828be811befe.png)
【React初心者メモ】型アノテーション（:）

# 型アノテーション（:）とは
型アノテーションとは、TypeScriptにおいて変数や関数の引数、戻り値の型を指定するものです。

# 具体例
基本：
```
//function関数
function greet(name: string) {
  console.log("こんにちは、" + name + "さん！");
}
greet("たろう"); 

//アロー関数
const greet = (name: string): void => {
  console.log(`こんにちは、${name}さん！`);
};
greet("たろう"); 
```
複数引数：
```
//function関数
function add(a: number, b: number): number {
  return a + b;
}

//アロー関数
const add = (a: number, b: number): void => {
  return a + b;
};
```
オブジェクトの引数：
```
//function関数
function printUser(user: { name: string; age: number }): void {
  console.log(`${user.name}は${user.age}歳です`);
}

//アロー関数
const printUser = (user: { name: string; age: number }): void => {
  console.log(`${user.name}は${user.age}歳です`);
};
```
配列の引数：
```
//function関数
function sumScores(scores: number[]): number {
  return scores.reduce((a, b) => a + b, 0);
}

//アロー関数
const sumScores = (scores: number[]): number => scores.reduce((a, b) => a + b, 0);
```
オプショナルな引数：
```
//function関数
//name?: string → name は文字列かもしれないし、無いかもしれない
function greet(name?: string): void {
  if (name) {
    console.log(`こんにちは、${name}さん！`);
  } else {
    console.log("こんにちは！");
  }
}

//アロー関数const greet = (name?: string): void => {
  if (name) {
    console.log(`こんにちは、${name}さん！`);
  } else {
    console.log("こんにちは！");
  }
};
```
デフォルト引数付き：
```
//function関数
function greet(name: string = "ゲスト"): void {
  console.log(`こんにちは、${name}さん！`);
}

//アロー関数
const greet = (name: string = "ゲスト"): void => {
  console.log(`こんにちは、${name}さん！`);
};
```
引数に配列の分割代入で型指定：
```
//function関数
function printCoords([x, y]: [number, number]) {
  console.log(`x: ${x}, y: ${y}`);
}

//アロー関数
const printCoords = ([x, y]: [number, number]): void => {
  console.log(`x: ${x}, y: ${y}`);
};
```
引数にオブジェクトの分割代入で型指定：

```
//function関数
function printProfile({ name, age }: { name: string; age: number }) {
  console.log(`${name}さんは${age}歳です`);
}
//アロー関数
const printUser = ({ name, age }: { name: string; age: number }): void => {
  console.log(`${name}さんは${age}歳です`);
};
```
エクスプローラーで指定用語のファイルを検索するバッチファイル

エクスプローラーでファイル名等を検索して特定のファイル検索しようとしても、膨大なファイル数が保存されているフォルダが対象だと、結局、検索ができないことがあります。

その場合は、エクスプローラーの検索ボックスで検索するのではなく、コマンドプロンプトで検索するとよいでしょう。
下記は、自身のダウンロードフォルダを検索するバッチファイルです。
実行後に検索したいキーワード（例：.pdf）を入力すれば、該当のファイルの一覧を出力してくれます。
対象とするフォルダは、必要に応じて変更してください。

```bat:Windowsバッチファイル
@echo off
setlocal

rem サンプル：サブディレクトリ内のログファイルを検索する
rem WHERE /R C:\Work *.* /T > 検索ファイルリスト.txt
rem ファイルサイズ、タイムスタンプ、ファイルのフルパス

:: 検索対象のフォルダを設定（例：ダウンロードフォルダ）
set "targetPath=%USERPROFILE%\Downloads"

:: 検索キーワードを入力
set /p "keyword=検索キーワードを入力してください（部分一致）: "

WHERE /R "%targetPath%" *"%keyword%"* /T > 検索ファイルリスト.txt

:: 完了メッセージ
echo 完了しました。結果はバッチファイル保存場所に出力されています。
pause
endlocal
```
バッチファイルの基本的な説明は、下記の記事等をご参照ください。
[【Qiita記事】：ノンプロ向けの便利なバッチファイルの使い道（業務効率化）](https://qiita.com/nanashi0424/items/b3a1a703b260a73954ab)
久しぶりの記事でした！
dbt_project.ymlの正しい理解がプロジェクト成功のカギ：フォルダ構成と実行エラーの落とし穴

<h3>背景：dbt活用が当たり前になった時代に必要な設定知識</h3>
<p>
近年、データ分析基盤のモダナイズにおいて<strong>dbt（data build tool）</strong>は欠かせない存在となっています。特に、SnowflakeやBigQueryなどのDWHと組み合わせた<strong>データ変換処理の自動化</strong>に強みがあり、エンジニア1〜3年目でも触れる機会が急増中です。
</p>
<p>
その中でも、プロジェクトの中核ファイルとなる<strong>dbt_project.yml</strong>は設定次第でプロジェクトの成否を左右します。本記事では、<strong>models配下にフォルダを作成してdbt runしたときに発生しがちな落とし穴</strong>に焦点を当て、エラー回避の実践Tipsまでを一貫して解説します。
</p>

<h3>dbt_project.ymlの役割と構成要素の基本</h3>
<p>
<strong>dbt_project.yml</strong>は、dbtプロジェクト全体の設定を定義するYAMLファイルで、プロジェクトの「設計図」ともいえる存在です。主に以下の情報が含まれます：
</p>
<ul>
  <li><strong>name：</strong>プロジェクト名</li>
  <li><strong>profile：</strong>接続先DWHのプロファイル名</li>
  <li><strong>model-paths：</strong>モデル（SQLファイル）の格納パス</li>
  <li><strong>models：</strong>各モデルのmaterializationやschemaの設定</li>
</ul>
<p>
特に<strong>models</strong>セクションは、フォルダ構造と密接に関係し、誤解したまま実行すると想定外の出力やエラーの原因になります。
</p>

<h3>よくある課題・エラーとその背景</h3>
<p>
実務でよく遭遇する課題やQiita上で注目された事例には、以下のようなものがあります：
</p>
<ul>
  <li><strong>--selectが効かない：</strong>フォルダ構成とdbt_project.ymlの記載が一致していない</li>
  <li><strong>意図しないスキーマや別名のテーブルが作られる：</strong>モデル設定の記載漏れや誤設定</li>
  <li><strong>モデルが認識されない：</strong><span style="color:red;">YAMLのインデントミス</span>やパス指定の漏れ</li>
</ul>
<p>
これらのエラーは、すべて<strong>models配下のフォルダ構成とdbt_project.ymlの記述のズレ</strong>によって引き起こされます。初心者がつまずく典型的なポイントです。
</p>

<h3>実践：フォルダ構成とdbt_project.ymlの正しい書き方</h3>
<p>以下に、正しいdbt_project.ymlの記載例とディレクトリ構成例を示します。</p>

<pre><code># ディレクトリ構成
models/
├── sales/
│   └── daily_sales.sql
├── marketing/
│   └── campaign.sql

# dbt_project.yml
name: 'my_project'
version: '1.0.0'
config-version: 2

profile: 'my_project_profile'

model-paths: ["models"]

models:
  my_project:
    sales:
      +schema: sales_schema
      +materialized: table
    marketing:
      +schema: mkt_schema
      +materialized: view
</code></pre>

<p>
このように、<strong>models.my_project.sales</strong>のようにフォルダ名とファイルパスが一致していないと、<span style="color:red;">dbt run時に対象モデルが見つからない</span>エラーが発生します。特に注意すべきは、<strong>プロジェクト名（name）とmodelsセクション直下のキーが一致していること</strong>です。
</p>

<h3>ベストプラクティスと運用Tips</h3>
<ul>
  <li>YAMLの<strong>インデント</strong>はタブではなくスペースで。構文エラーの元。</li>
  <li><strong>ディレクトリ構成を事前に設計</strong>し、modelsセクションと照合しながら記述。</li>
  <li>モデルを追加したら、<strong>dbt debug</strong>と<code>dbt ls</code>で対象モデルが認識されているか確認。</li>
  <li>materializationやschema指定は、<strong>フォルダ単位</strong>で共通設定すると管理が楽。</li>
  <li>必要に応じて、<strong>--select フォルダ名.ファイル名</strong>で個別実行テストを行う。</li>
</ul>

<h3>まとめと今後の展望</h3>
<p>
dbtプロジェクトにおける<strong>dbt_project.yml</strong>の設定は、プロジェクトの実行性・保守性を大きく左右する重要な構成要素です。特にmodelsディレクトリ配下の構成を正しく管理することで、エラーを未然に防ぎ、チーム開発や本番運用への移行もスムーズに行えます。
</p>
<p>
今後、CI/CDやAirflowと連携する際にもこの設定の正確性が前提となるため、<strong>早い段階で正しい理解と設計パターンを身につける</strong>ことが、モダンデータスタックを扱う上での大きな武器となるでしょう。
</p>
プレイスメントグループ

AWSのプレイスメントグループ（Placement Group）は、EC2インスタンスを**物理的にどのように配置するか**を制御するための機能です。要件に応じて、以下の3種類の戦略があります。

---

## 🧩 1. クラスタープレイスメントグループ（Cluster Placement Group）

### 🔹 特徴

* **同じアベイラビリティゾーン内の近接したハードウェア**にインスタンスを配置。
* **超低レイテンシー・高帯域**通信が可能。
* HPC（ハイパフォーマンスコンピューティング）用途に最適。

### ✅ 使うべきケース

* 大量のデータを高速でやり取りする必要があるアプリケーション。
* MPIなどの分散処理、科学計算、金融モデリングなど。

### ⚠ 注意点

* インスタンス起動に失敗することがある（キャパシティ不足）。
* スケールアウトよりスケールアップに向く。

---

## 🧩 2. パーティションプレイスメントグループ（Partition Placement Group）

### 🔹 特徴

* **1グループ内に最大7つのパーティション**（ラック単位の分離）を持つ。
* 各パーティションは物理的に独立（電源、ネットワーク等が異なる）。
* 各パーティションに複数のEC2を配置できる。

### ✅ 使うべきケース

* **大規模な分散システム**（例：Hadoop、Cassandra、Kafka）。
* 1つのラック障害で全体停止しないようにしたいとき。
* **高可用性＋スケーラビリティ**の両立が必要なケース。

### ⚠ 注意点

* AZは1つに限定（AZをまたがない）。
* 各パーティション間の通信レイテンシはやや高め。

---

## 🧩 3. スプレッドプレイスメントグループ（Spread Placement Group）

### 🔹 特徴

* **1つの物理ホストやラックに1つのインスタンスのみ配置**。
* 最大7インスタンスまでAZ単位で分離される。
* **ハードウェア障害の影響を最小化**。

### ✅ 使うべきケース

* インスタンス数は少なくて良いが、**高可用性が最重要**な場合。
* 各インスタンスが重要なシステム（例：マスター/リーダー）で、同時障害を避けたい。

### ⚠ 注意点

* スケールに制限がある（同一AZ内で7台まで）。
* コストは高めになる（分散配置されるため）。

---

## 📊 比較表

| 項目       | クラスター     | パーティション                | スプレッド          |
| -------- | --------- | ---------------------- | -------------- |
| 目的       | 高速通信      | 高可用・分散                 | 高可用・分離         |
| 物理配置     | 近接        | パーティション単位で分離           | ホスト／ラック単位で完全分離 |
| 通信レイテンシ  | 最小        | やや高い                   | 高い（距離が遠い）      |
| スケーラビリティ | 中程度       | 高                      | 低（最大7台）        |
| 耐障害性     | 低         | 中〜高                    | 高              |
| 代表ユースケース | HPC, 分散処理 | HDFS, Kafka, Cassandra | マスター系の冗長化構成    |

---

## 🧠 使い分けまとめ

* 🔧 **高速通信が必要 → クラスター**
* 🏗 **分散処理＆ラック障害に備えたい → パーティション**
* 🧷 **インスタンス1台ずつが重要 → スプレッド**
AWS SCT

AWS SCT（**AWS Schema Conversion Tool**）とは、オンプレミスや他クラウドの **データベーススキーマやSQLコードを、AWSのターゲットDBに変換するツール** です。

主にデータベース移行の際に使用されます。

---

## ✅ 主な目的

**異種データベース間の移行**（例：Oracle → Amazon Aurora、SQL Server → Amazon RDS for PostgreSQL）において、スキーマやストアドプロシージャ、ビュー、関数などを **ターゲットDBの構文に変換**します。

---

## 🔄 対応する変換の例

| ソースDB（移行元）                  | ターゲットDB（移行先）                           |
| --------------------------- | -------------------------------------- |
| Oracle                      | Aurora PostgreSQL / RDS for PostgreSQL |
| SQL Server                  | Aurora MySQL / RDS for MySQL           |
| MySQL                       | Aurora PostgreSQL                      |
| PostgreSQL                  | Aurora MySQL                           |
| Db2 / SAP ASE / Teradata など | 各種AWS DB                               |

---

## ⚙️ 主な機能

| 機能       | 内容                                                 |
| -------- | -------------------------------------------------- |
| スキーマ変換   | テーブル定義、インデックス、ビュー、トリガーなどを変換                        |
| SQL変換    | ストアドプロシージャ、関数、パッケージなどのコード変換                        |
| 自動レポート生成 | 移行可能な項目・変換が必要な項目を可視化したレポートを出力                      |
| DMS連携    | AWS Database Migration Service（DMS）と組み合わせてデータも移行可能 |

---

## 💡 こんなときに使う

* オンプレの Oracle を AWS 上の PostgreSQL に移行したい
* SQL Server のプロシージャを Aurora MySQL 互換で動かしたい
* 移行前に「どのくらい手動対応が必要か」分析したい

---

## 🖥️ 利用方法（概要）

1. AWS SCT をインストール（Windows, macOS, Linux対応）
2. ソースDB・ターゲットDBに接続
3. スキーマのスキャン → 変換レポートを確認
4. 自動変換できる部分は変換して出力
5. 手動で必要な部分を修正
6. DMSなどでデータも移行

---

## 📈 移行レポート例

移行評価レポートでは、以下のように表示されます：

| カテゴリ       | 状態          |
| ---------- | ----------- |
| テーブル定義     | ✅ 自動変換可能    |
| ビュー        | ⚠ 一部手動対応    |
| ストアドプロシージャ | ❌ サポート外構文あり |
| トリガー       | ✅ 一部変換可能    |

---

## 📌 まとめ

| 項目     | 内容                               |
| ------ | -------------------------------- |
| ツール名   | AWS Schema Conversion Tool (SCT) |
| 主な目的   | 異種DB間のスキーマ／コード移行支援               |
| 特徴     | 自動変換、変換レポート、DMSとの連携              |
| 対象ユーザー | オンプレ→AWSのDB移行を行うエンジニアやDBA        |
| 無料     | ✅ 利用は無料（GUIツール）                  |

---
CloudWatch LogsのInsightでLambdaのログをガバっと取得する手順

個人的備忘録。
最近これを使うことが増えたので、理解したことを忘れないようにしていく。

インサイトの画面 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/a2328919-de80-44fe-90cc-4bf774d54b8c.png)

画面右上にある、ローカルタイムゾーンとかUTCタイムゾーンとかでインサイト上で表示する時刻を指定することが出来る。また、その左側にある時刻のやつはログを取得する時間帯を指定することが出来る。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/9649fbd1-0625-4d35-9b92-8074af85e9d8.png)

絶対値を指定するとより細かく条件を指定することが出来る
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/e189c89e-9244-4977-bfa0-6a8d50cfb733.png)

こんな感じに
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/fed32e79-ba51-47c7-9bfd-a0f3f57d0b04.png)

ロググループを使ってログを取得するサーバ？を指定することが出来る。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/eeb6557f-8ec0-4fd6-a151-0864c0a7acfa.png)

今回は、以前構築したLambdaを選択してみた。
勿論Lambdaだけではなく、EC2を指定することもできる（ただし、Agentを導入してLogsにログを出力している場合）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/4ac74bc3-0d39-4722-b73e-48e788bd1f0d.png)

ここで取得するログを細かく指定することが出来る。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/af07825f-243f-4848-96fb-060865714bd2.png)

デフォルトはこのようになっている。
limitは取得するログの行数的なイメージで良さそう。
10000より上は指定できない。もし10000よりたくさんあるなら日時指定をより細かくしていくか、取得するログをより絞るしかない
```
fields @timestamp, @message, @logStream, @log
| sort @timestamp desc
| limit 10000
```

日時を過去→げんざにするためにはdescではなくascの方が良い。
```
fields @timestamp, @message, @logStream, @log
| sort @timestamp asc
| limit 10000
```

クエリを実行してみる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/fd6a99ab-cc6e-4f5c-9cbf-5a882ff59952.png)

指定のログがあるとこのように出力される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/de62224b-0bfa-4654-b33d-ca23fe2ceb64.png)

エクスポートすることも出来る。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/3e47a4fa-80e6-4597-b1bd-c6428cd492a2.png)

エクスポート結果は以下。最初の数行だけをサンプルとしてここに掲示する。
タイムスタンプがCloudWatchのものと異なるが、CSVで出力する時はUTC表記になってしまうため。
JSTの場合ログに記載の時間+9時間で考えないといけないっぽい。
```csv
@timestamp,@message,@logStream,@log
2025-05-04 10:58:32.781,"START RequestId: 814c5eb9-8ba4-4365-92b2-01287418d169 Version: $LATEST
",2025/05/04/[$LATEST]a2141d61bd2949c9b89d3ccc07118b7a,535002847634:/aws/lambda/Hello-REST-API
2025-05-04 10:58:32.801,"END RequestId: 814c5eb9-8ba4-4365-92b2-01287418d169
",2025/05/04/[$LATEST]a2141d61bd2949c9b89d3ccc07118b7a,535002847634:/aws/lambda/Hello-REST-API

```

クエリを少し修正する
これはメッセージ部分にlambdaを含むものという感じで更に絞っているイメージ。
```
fields @timestamp, @message, @logStream, @log
| filter @message like /lambda/
| sort @timestamp asc
| limit 10000
```

実行結果が以下。ログの出力がグッと減った。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/c4d5a5bb-929e-4d3d-9dd1-8fd8bbb20dd8.png)


インサイトの料金はこちらを参考
クエリ (Logs Insights)	USD 0.005/スキャンされたデータの GB

https://aws.amazon.com/jp/cloudwatch/pricing/
【React初心者メモ】無名関数

# 無名関数とは
無名関数とは、その名の通り「名前のついていない関数」のことです。

通常の関数：
```
function greet() {
  console.log("こんにちは");
}
```
無名関数：
```
// function() のあとに関数名がない
const greet = function() {
  console.log("こんにちは");
};
```

# 使われる場面
1．変数に代入して使う

アロー関数：
```
const sayHello = () => {
  console.log("Hello!");
};
sayHello();
```
fuction関数：
```
const sayHello = function() {
  console.log("Hello!");
};
sayHello();
```

2．引数として関数を渡すとき（コールバック関数）

アロー関数：
```
setTimeout(() => {
  console.log("1秒後に表示されます");
}, 1000);
```
fuction関数：
```
setTimeout(function() {
  console.log("1秒後に表示されます");
}, 1000);
```

3．配列の高階関数（map, filterなど）で使う

アロー関数：
```
const nums = [1, 2, 3];
const doubled = nums.map(num => num * 2);
```
fuction関数：
```
const nums = [1, 2, 3];
const doubled = nums.map(function(num) {
  return num * 2;
});
console.log(doubled); // [2, 4, 6]
```
Python標準ライブラリ徹底比較：sys・os・pathlib・shutil の使い分けと違いまとめ（自分用）

📝 概要
--
Pythonには標準ライブラリとして sys や os、さらには pathlib や shutil などの「システムまわり」の操作に使えるモジュールが豊富にある。
この記事では、それぞれのモジュールの役割・違い・使い分けポイントを実例とともに整理する。

🧭 ざっくり全体マップ
--
| モジュール     | 主な用途              | 操作対象         |
| --------- | ----------------- | ------------ |
| `sys`     | Python処理系の制御      | コマンドライン・実行環境 |
| `os`      | OSとの連携            | ファイル・ディレクトリ  |
| `os.path` | パス操作              | 文字列ベースのパス    |
| `pathlib` | モダンなパス操作          | パスオブジェクト     |
| `shutil`  | ファイル・ディレクトリの高水準操作 | コピー、移動、削除など  |

✅ sys：Python自身を制御する
--
主な機能
sys.argv: コマンドライン引数の取得
sys.exit(): プログラムの終了
sys.path: モジュール検索パス
sys.version: 実行中のPythonバージョン
```python:example.py
import sys

if len(sys.argv) < 2:
    print("引数が不足しています")
    sys.exit(1)

print("1つ目の引数:", sys.argv[1])
```

✅ os：OSとのやりとりを担当
--
主な機能
os.getcwd(): 現在のディレクトリを取得
os.listdir(): ファイル一覧を取得
os.environ: 環境変数を取得・設定
os.remove(), os.rename() などのファイル操作
```python:example.py
import os

print("カレントディレクトリ:", os.getcwd())

if os.path.exists("sample.txt"):
    os.remove("sample.txt")
```

✅ os.path：文字列でパスを操作したいときに
--
主な機能
os.path.join(): パスの結合
os.path.exists(): ファイルやディレクトリの存在確認
os.path.splitext(): 拡張子の取得
```python:example.py
import os

filepath = os.path.join("data", "file.txt")
print("存在確認:", os.path.exists(filepath))
```

✅ pathlib：モダンなパス操作（Python 3.4～）
--
os.path の代替として注目される新しい標準モジュール。

主な特徴
文字列でなく パスオブジェクト を使う
メソッドチェーンで直感的に書ける
ファイル・ディレクトリの存在確認、読み書きも可能
```python:example.py
from pathlib import Path

p = Path("data") / "file.txt"
if p.exists():
    print("ファイルがあります:", p)
```
補足
os.path.join("data", "file.txt") と同等の処理が Path("data") / "file.txt" で書ける。とても直感的！

✅ shutil：ファイル・ディレクトリの高レベル操作
--
shutil.copy(), copy2()：ファイルのコピー
shutil.move()：移動（リネーム含む）
shutil.rmtree()：ディレクトリの再帰削除
```python:example.py
import shutil

shutil.copy("example.txt", "backup/example.txt")
```

🔁 似ているけど違う：使い分けマトリクス
--
| やりたいこと           | おすすめモジュール            | 理由                     |
| ---------------- | -------------------- | ---------------------- |
| 引数でファイル名を渡したい    | `sys.argv`           | Python起動時のコマンドライン引数    |
| ファイルが存在するか確認したい  | `pathlib`, `os.path` | `pathlib`がより可読性が高くおすすめ |
| ディレクトリを再帰的に削除したい | `shutil.rmtree()`    | 高レベルの操作に対応             |
| モジュールの検索パスを追加したい | `sys.path.append()`  | 実行時のモジュール読み込みに影響       |
| ファイルをコピーしたい      | `shutil.copy()`      | `os` にはコピー機能がないため      |

📌 Tips：どれを選ぶべき？
--
| 操作対象       | 推奨モジュール              | 備考                      |
| ---------- | -------------------- | ----------------------- |
| パス（結合・操作）  | `pathlib`            | Python 3.4以降で強く推奨       |
| ファイルの中身操作  | `open()` + `pathlib` | `Path.read_text()` も便利  |
| ディレクトリ再帰削除 | `shutil.rmtree()`    | `os.rmdir()` は空ディレクトリのみ |

🧩 まとめ
--
| モジュール     | 対象            | 主な使い所                    |
| --------- | ------------- | ------------------------ |
| `sys`     | Python本体      | 引数、終了制御、バージョンチェックなど      |
| `os`      | OS全般          | 環境変数、ファイル削除、カレントディレクトリ取得 |
| `os.path` | 文字列パス         | 旧来のパス結合、存在確認、拡張子取得など     |
| `pathlib` | パスオブジェクト      | パス操作のモダンなやり方    |
| `shutil`  | ファイル/ディレクトリ操作 | コピー、移動、削除などの高レベル操作       |

💬 最後に
--
今までなんとなく使っていたけど、os、sys、pathlib…実はそれぞれ得意分野がありそうだなと感じた。
PostgresqlのDBコピー/テーブルコピー方法

# PostgreSQLでデータベース・テーブルをコピーする方法まとめ

PostgreSQLを使っていて、以下のような場面で**データや構造をコピーしたい**ケースは多いと思います。

- テーブルのバックアップを取りたい
- テスト用DBを本番から複製したい
- スキーマ間でデータを移動したい

本記事では、以下の2つのケースについて解説します。

- ✅ データベース単位のコピー
- ✅ テーブル単位のコピー（スキーマ間を含む）

---

## 1. コマンドプロンプトでファイルの移動
コピーの操作については、コマンドを実行します。そのさいに、`PostgreSQL`の`binフォルダ`にパス（環境変数の設定）が通っている必要があります。
もし通っていない場合、`cd`コマンドでbinフォルダまで移動します。
```bash
cd C:\Program Files\PostgreSQL\16\bin
```

---

## 2. データベースのコピー方法（pg_dump → psql）

### 2-1. ダンプファイルを作成

#### 🔧 基本構文
```bash
pg_dump -U <ユーザー名> -d <データベース名> -f "<出力先の絶対パス>\<ファイル名>.sql"
```

#### 💡 使用例
```bash
pg_dump -U postgres -d testdb -f "C:\dump\testdb_dump.sql"
```
#### ✅ ポイント
+ -U postgres: ユーザー名
+ -d testdb: コピー元のDB名
+ -f: 出力ファイル（フルパスで指定）
+ ⚠ 出力フォルダに書き込み権限があるかも確認。アクセス拒否エラーが出る場合は、ユーザーディレクトリ直下などの安全なパスを指定

### 2-2. 新しいデータベースを作成

#### 🔧 CREAT文
```sql
createdb -U postgres testdbbk
```

### 2-3. ダンプを新しいDBにリストア

#### 🔧 基本構文
```bash
psql -U <ユーザー名> -d <2-2.で作成したデータベース名> -f "<2-1.で出力したdumpファイルを格納している場所の絶対パス>"
```

#### 💡 使用例
```bash
psql -U postgres -d testdbbk -f "C:\dump\testdb_dump.sql"
```
#### ✅ ポイント
+ -U postgres: ユーザー名
+ -d testdb: コピー元のDB名
+ -f: 出力ファイル格納場所（フルパスで指定）

---

## 3. テーブルのコピー方法

### 3-1. テーブル定義・インデックス・制約込みで複製

#### 🔧 CREATE文
```sql
CREATE TABLE <コピー先テーブル名> (LIKE public.<コピー元テーブル名> INCLUDING ALL);
```

#### 💡 使用例
```sql
CREATE TABLE public.testtable_bk (LIKE public.testtable INCLUDING ALL);
```
#### ✅ ポイント
+ `INCLUDING ALL`を使うと、カラム定義・デフォルト値・NOT NULL 制約・CHECK制約・インデックスなど全て含まれる

### 3-2. データをコピー

#### 🔧 INSERT文
```sql
INSERT INTO <コピー先テーブル名> SELECT * FROM <コピー元テーブル名>;
```

#### 💡 使用例
```sql
INSERT INTO public.testtable_bk SELECT * FROM public.testtable;
```

---

## ✅ まとめ

| 方法                        | 内容                                           |
|-----------------------------|------------------------------------------------|
| `pg_dump` + `psql`         | DBをまるごとバックアップ・リストアする         |
| `CREATE TABLE ... LIKE`    | テーブル定義を丸ごとコピーする                |
| `INSERT INTO ... SELECT`   | テーブルデータのみをコピーする                |
【React初心者メモ】アロー関数

# アロー関数とは
アロー関数とは、JavaScriptで関数を簡潔に書くための表現です。

通常の関数：
```
function greet(name) {
  return "Hello, " + name;
}
```
アロー関数：
```
const greet = (name) => {
  return "Hello, " + name;
};
```

# 様々な書き方
戻り値の型を指定する
```
const func = (x: number): number => {
  return x * 2;
};
```
1つの引数の場合はカッコ省略可能
```
const greet = name => {
  return "Hello, " + name;
};
```
処理が1行（returnだけ）の場合は中括弧（{}）とreturnも省略できる
```
const greet = name => "Hello, " + name;
```

```
onst sayHello = () => "Hello!";
```
Q developer君で見慣れないくにおくんライクゲームができたから見て

こんにちは
新米インフラエンジニアの稲穂です。
この前の続きも書きたかったんですが、いろいろ言い訳のび太君をかましており、先にQくんでゲーム作るとTシャツ貰えちゃうキャンペーンに応募したくて記事を書いてみました。
不純上等！シクヨロ！

現在開催中の「Amazon Q CLI でゲームを作ろう」キャンペーンでは、2025 年 5 月 20 日から 6 月 20 日までにAmazon Q CLI でゲームを作って、その結果をブログ・SNSに投稿すると、Amazon QブランドのTシャツをゲットすることができます。
https://aws.amazon.com/jp/blogs/news/build-games-with-amazon-q-cli-and-score-a-t-shirt/

AIコーディングアシスタントであるAmazon Q CLIくんで、Pygameで簡単なゲームを開発、事前準備や開発の流れを投稿みんなもしよう！

こちらにそってQ君、をインストールしてくださいね。
上手くいくと画像のようにロゴが出てくれるので下記を打つと日本語で話してくれます。
pls japanese 

↓Amazon Q CLI
https://docs.aws.amazon.com/ja_jp/amazonq/latest/qdeveloper-ug/command-line-installing.html

![スクリーンショット 2025-06-07 13.20.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4046203/34389eea-9881-48a6-bbbf-30934ee19fb6.png)

↓PyGame
https://www.pygame.org/wiki/GettingStarted

どうせなら格闘ゲームでみんなでワイワイ楽しそうなのがいいと思い
大好きな熱血くにおくんライクなゲームを目指してみた結果がこちらです。
男はステゴロ！

![スクリーンショット 2025-06-07 10.38.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4046203/bdea129d-4552-47da-972d-4815afee6764.png)

くにお・・・・？
お前どこいった・・・？
リーゼント真っ平磯海苔だとどちらかというと元さんやガイルさんやぞ。

学ランの下で尻子玉見せる仕様はいろいろ危険ぞ・・・？

ちょっと強気で前向きなQ君の回答がこちら
![強気なQくん.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4046203/e437e7ba-56c0-4d16-b7e4-492fc2fc41d4.png)

学校屋根で三角西洋式でした。世界観混ざっとる！Q君との文化の違いを楽しみましたよ。
Qiitaには貼れなかったのですが動画はこちら
https://x.com/e_o_rice/status/1931200203618664614

もっと上手くプロンプトできるようになって
関節外し投げくにおくんをいつか熱血くにおくんにしたい。
初心者でもゆるゆるゲーム作成ができちゃうQ君、
AWS様楽しい時間をありがとうございました。
SAA受かったらもっとQ君と作り込んでいこう。
No-Codeで簡単にウェブサイトが作れる「YouWare」を試してみました

最近、友達からのおすすめで「YouWare」というサービスを試してみました。YouWareはAIを使って、No-Codeでウェブサイトを作れるサービスです。自分のプロフィールページや小規模なコミュニティサイトを作る際には活用できると感じました。

https://www.youware.com/


## 実際に試した流れ

まず、[YouWare](https://www.youware.com/)にアクセスすると、チャット形式の入力欄が表示されます。今回は特に個人情報などを入力せず、「個人のプロフィールサイトを作って」とだけ指示をしました。

約30秒ほどで以下のようなサイトが完成しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3556459/729fb4b4-a0c7-46e5-a48c-d34ba0eb0775.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3556459/1885277d-d4dc-41bb-bdd5-8fce9acd2c1e.png)

シンプルで悪くない仕上がりですね。

右下に「Boost」というボタンがあり、それをクリックすると、デザインが自動的に改善されます。今回は約1分で以下のようにアップグレードされました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3556459/a9c674fc-537a-4186-9995-998a359b0995.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3556459/202e97af-e7f4-48b0-bbcd-17bc3cd03065.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3556459/c8b48d32-2d52-4d68-baa2-ef1a168ddebc.png)

全体的に見栄えが良くなりましたが、さらにデザインを改善したかったので、もう一度「Boost」をクリックしました。今回はAgentによるreflectionが何度か繰り返され、約5分ほどかかりましたが、結果としてより洗練されたデザインになりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3556459/83f1b1de-9e60-44db-b75f-acb2b90766cc.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3556459/55ad3fe1-9d73-45d1-928f-557c912c2f33.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3556459/836c9663-fee9-4652-b3c1-fd4c9ec06bd2.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3556459/7497b3af-6fde-46dc-b4a5-fcd298919e0a.png)

最終的にはかなり良い仕上がりで、最近のトレンドを取り入れたデザインになりました。最後は右上の「Publish」ボタンを押すと、そのままウェブサイトが公開されます。以下が実際に作成したサイトです。

https://www.youware.com/project/w9j5uzglbk

いかがでしょうか。Youwareを使えばこういう簡単なサイト開発はすぐできますので、興味ある方は試してみてください。

https://www.youware.com/
【技術調査】S3 Access Grants について情報整理してみた

いつも記事を読んでいただきありがとうございます！
モブエンジニア（[@mob-engineer](https://qiita.com/mob_engineer))です！

久しぶりに個人用AWSアカウントを触っていたところ、S3のメニュー内でふと目についた項目がありました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3846878/9435d854-5e3c-42bc-b1c9-115e34b3a377.png)

個人的に知らないS3サービスでしたので、簡単に調査してみたいと思います。

初見の方でもサクッと読めるように平易な表現で執筆しておりますので、お気軽にお読みいただければ幸いです。

# 目次
- Access Grantsとは
    - 概要
    - 利用料金
    - アップデート情報
- 触ってみる
- ユースケース

## Access Grantsとは

コンソール上のトップページを見てみると次のように示されていました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3846878/18720158-c089-4cc4-b369-93fe3880d2eb.png)

ざっくり言えば、**社内文書などの特定ユーザにしか見せられないドキュメントを管理するためのS3**と思ってもらえればわかりやすいかと思います。


### 概要

AWS公式ドキュメント上では次のように説明されていました。

>最小特権の原則に従うには、アプリケーション、ペルソナ、グループ、または組織単位に基づいて Amazon S3 データへのきめ細かなアクセスを定義します。アクセスパターンの規模と複雑さに応じて、さまざまなアプローチを使用して Amazon S3 のデータへのきめ細いアクセスを実現できます。
Amazon S3 内の少数から中程度の数のデータセットへのアクセスを AWS Identity and Access Management (IAM) プリンシパルで管理する最も簡単な方法は、IAM アクセス許可ポリシー と S3 バケットポリシー を定義することです。この戦略は、必要なポリシーが S3 バケットポリシー (20 KB) と IAM ポリシー (5 KB) のポリシーサイズ制限内に収まり、アカウントごとに許可されている IAM プリンシパルの数内である限り有効です。

https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/access-grants.html

そのうえで、S3 Access Grantsを利用するうえで専用のインスタンスをあらかじめ構築する必要があります。

https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-grants-instance.html

メリットは様々ありますが、**IAMでのきめ細やかな権限管理**を実現できることがあると考えています。（ファイルサーバを構築するノリでS3を利用できるイメージですかね）

### 料金

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3846878/c8f9dcfd-5dd8-4e13-a4c3-f59bab5a9d6b.png)

:::note info
料金表にも記載されていますが取得（GET）に対して料金が発生します。そのため、削除（DELETE）に対しては料金が発生しません。
:::

### アップデート情報

アップデート情報としては次の通りです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3846878/ccdc4dc7-c75d-4024-a7a4-240d27479715.png)

個人的には、SageMakerとの統合やAWS Glueとの統合はデータエンジニア視点ではうれしいポイントが多くあるのではないかなぁと思っています。

## ユースケース

セキュリティ強度を向上させるといったところが本機能の肝かと思います。
そのため、以下ユースケースで利用するのがベターかと思います。

- ETLパイプラインと統合してデータ分析を行いたいが機密性が高い情報を格納する場合
- 社内文書など社外ユーザからのアクセスを防ぎたい場合
- とりあえず、社内文書管理ストレージを作成したい場合

今回はざっくりと調べただけですが、個人的に気になる機能でした。
今後、ハンズオン形式で構築方法をまとめてみたいと思います。

最後まで記事をお読みいただきありがとうございます！！
1年前までPCを持っていなかった僕がエンジニアになるためにやったこと全部



こんにちは。この記事では、僕がエンジニアになるまでに実際にやったことを、リアルに振り返って書いてみたいと思います。

僕は現在26歳で、スタートアップの受託開発企業でエンジニアとして働いて半年が経ちました。
1年前の2024年5月までは、パソコンすら持っていなかったところからのスタートでした。

そんな僕でも今、PythonでAPI開発をしたり、AWSやSQLを扱ったり、LLMに興味を持ちながら日々技術を学んでいます。
この1年、どんな風に学び、成長してきたのかを書いてみました。

## ✅ エンジニアになる前、何をしていた？

大学卒業後は、建築資材を扱う商社で営業として2年間働いていました。退職後はフィリピン留学に行っていて、あるIT企業のCTOと出会ったことが大きな転機でした。
帰国後、本格的にエンジニアを目指して勉強を開始。
CTOには月1ペースで面倒を見てもらいながら、独学＆就活を進めていきました。

## ✅ エンジニアになるまでにやったこと

まず最初に手を出したのが、Progateです。
そこから「Railsチュートリアル」を2周して、自分のポートフォリオとしてマッチングアプリを開発しました。

初めはRubyのの技術理解を深めるために、輪読会を開催（毎週月曜21時、通称“月9の裏番組”）し、1章ずつレジュメを作って発表しながら進めました。

ポートフォリオ作成の中で「詰まったエラーがどうしても解決できない」という壁にもぶつかりました。
書籍やネットだけではわからなかったので、オフラインの勉強会に参加。
今思えば簡単なエラーだったかもしれませんが、当時の自分にとっては大きな経験でした。

休日は7〜8時間、仕事の合間も可能な限り勉強。
1人で黙々とやるだけでなく、他の人と勉強内容を共有することも意識していました。

## ✅ エンジニアになってからの学び

今はPythonを使ったAPI開発が主な業務です。
一番苦労したのはGitHubの使い方。個人開発の時と違い、チームでは「ミスできない」プレッシャーがあり、かなり慎重に扱うようになりました。

最近は、AWSやSQL、生成AI（LLM）などにも興味を持って勉強しています。

読んだ本はこんな感じです：

- Webを支える技術

- ソフトウェアアーキテクチャの基礎

- プリンシパル オブ プログラミング

- プログラムはなぜ動くのか

- Effective Python

などなど...

加えて、FastAPIのハンズオン動画を購入し、実際に手を動かして学ぶようにしています。

## ✅ 勉強していて思ったこと

わかることが増えてくると、勉強がどんどん楽しくなってきます。
最初は何もわからなくて不安だし、全部が難しく見えるけど、やっていくうちにだんだん興味が湧いてきます。

詰まったら、「環境を変える」のが個人的にはおすすめ。
例えば、
- オフライン勉強会に参加して他のエンジニアと話す

- 書籍に飽きたら競技プログラミングをやってみる

とにかく「気張らず、続ける」ことが大事だと思います。

## ✅ エンジニアになって得たこと

エンジニアという職業は、技術力だけじゃなくて「仕事の仕方」も学べる職種だと感じています。

- タスクを細分化し、小さな単位で進めていく

- 進捗を聞かれる前に自分から報告する（Slackなどで一方的にでもOK）

- 質問する時はYes/Noで答えやすいように設計する

- スタンプだけで返事できるようにする

こういう工夫を積み重ねることで、チームでの開発がうまく回っていくことを学びました。

また、他人の意見を尊重する姿勢や、別のコミュニティでアウトプットする習慣も身につきました。
何度もエラーに出会って、それをひとつひとつ解決することの積み重ねが、力になっていると実感しています。

## ✅ おすすめの勉強法

インプットとアウトプットのバランスがとにかく大事。

どちらかに偏ると伸びにくいです。理解したらすぐに誰かに話す、ブログに書く、Xでつぶやくなど、どんな形でもアウトプットしましょう。

「Webを支える技術」のような構造的な知識は、もっと早く読んでおけば良かったなと後悔しています。仕組みがわかることで、エラー対応の引き出しも増えます。

## ✅ 習慣にしていてよかったこと

X（旧Twitter）で日々の勉強状況や、読んだ本、悩んだことを投稿するようにしています。

これが結果的に、良い振り返りになっていますし、アウトプットのハードルを下げてくれます。
たまに共感してくれる人や、アドバイスをくれる人がいるのも嬉しいですね。

## ✅ 最後に：1年前の自分へ

この1年で、本当にたくさんのことができるようになったと思います。
でもそれは、特別な能力があったからじゃなくて、続けてこれたからです。

焦らず、少しずつでも続けていれば、技術は必ず身につく。環境や人の力を借りるのも恥ずかしいことじゃない。

これからもエンジニアとしての道を進んでいきます。この記事が、誰かの一歩目を後押しできたら嬉しいです。

ありがとうございました！
コーディング初心者がpaizaラーニングでどこまでスキルを獲得することができるのか.day3

本日はメソッドです。

ここで、１日目の記事を見返していて思ったのが明らかに動かないコードを書いてしまっていたということです....申し訳ありません。

# メソッドとは？
一定の処理のプログラムに名前を付けることができる機能のことです。pythonでいう関数のようなものです。（本当は違いがあるそうですが）今の私にはそこまで理解できないので、解釈はいったんこれぐらいで。

実際に書いていきましょう。
```csharp
public class Lesson
{
    public static void Main()
    {
        SayHello();
    }

    public static void SayHello()
    {
        Console.WriteLine("Hello world");
    }
}
```
このプログラムで実行されたときに実行される部分はMain()のブロックでSayHello()はMainで呼び出さない限り使用することができません。
私が今定義した部分は
```csharp
public static void SayHello()
{
    Console.WriteLine("Hello world");
}
```
です。メソッドの使い方は以上です。

## 引数を指定したいとき
まず、引数って？という人のために簡単に説明しておくと、先ほどのメソッドはただ「Hello World」というだけなのですが、メソッドを呼び出すときに何か数値、文字を指定してその入力に基づいて出力を変えることができるという機能（？）です。具体例を見てみましょう。
```csharp
public class Lesson
{
    public static void Main()
    {
        SayHello(player);
    }

    public static void SayHello(string name )
    {
        Console.WriteLine(name + "Hello world");
    }
}
```
メソッド名を書いた後→（型の名前 メソッド内で使用する名前）で指定することができます。引数を追加したいときは（）の中で" , "を追加して同じルールーで記述してあげたらOK


ここまで学習して、毎回お世話になっているConsole.WriteLine()もメソッドであることがわかります。今まで無意識に利用していたことがわかりました。ちなみにメソッドを呼び出すときに異なる型で呼び出してしまうとエラーをはかれてしまうのでそこは注意しておきましょう。
CodeIQ:「エース・ナンバー」問題の解答

Kawazoe(@riverplus)さんのCodeIQの問題です。
問題はこちらのお世話になりました。解答もあります。
->https://oraclesqlpuzzle.ninja-web.net/kyoupro-old/kyoupro-04-004.html
こちらにも情報があります
->https://posfie.com/@riverplus/p/2gI0RCN

16進数のAをn個並べた数をF(n)とするとき、F(n)を10進数で表したものを
10^6で割った剰余を求める問題です。

剰余の周期性を利用して解く方法もありますが、
等比数列の和を求める公式と逆元を用いた方法で解きました。

F(n)を10進数で表したものをf(n)としますと、Aは10進数の10ですので、
f(n)=10+10\*16+10\*16^2+...+10\*16^(n-1)
    =10*(16^n-1)/(16-1) = 2*(16^n-1)/3

16^nは繰り返し2乗法で解きます。（powmod(n,x)）
ループごとに計算結果の10^6による剰余を求め、次のループの元とします。
最後に2を掛けて3で割りさらに10^6による剰余をもとめますが、
一般にxで割った商のmによる剰余を求めるときは、xで割る代わりに
x*y≡1(mod m)となるy(mod m におけるxの逆元)を掛けてからmによる剰余を
求めなければなりません。
10^6と3が互いに素なのでmod 10^6での3の逆元が存在します。
Juliaには逆元を求めるinvmodという関数があり楽です。

```Julia
#julia ver 1.41,1.53,1.10.5

function solve(n,a)
  function powmod(n,x)
    ret = 1
    while n > 0
      d,r = divrem(n,2)
      if r == 1
         ret = mod(x*ret,m)
      end
　　  x = mod(x*x,m)
    　n = d
    end
    ret
　end
  m = 10^6
  x = mod(2*(powmod(n,16)-1) * invmod(3,m),m)
 s = a == x ? "ok " : "no "
 println(s,x) 
end

solve(5, 699050)
solve(10, 751850)
solve(20, 137450)
solve(1237, 689770)
solve(12345, 289450)
solve(8967452301, 708010)
solve(9876543210, 143850)
solve(10000000000, 406250)

```
Prologでは逆元を求めるのに拡張ユークリッドの互除法を使っています。

```Prolog
%SWI-Prolog ver 7.42,7.64,9.29
%:-initialization(start).   %ideone,Online Prolog Compiler
%start.

powmod(_,0,_,R,R).
powmod(M,N,P,R1,R):-
    divmod(N,2,X,Y),P1 is P*P mod M,(Y =:=1->R2 is R1*P mod M;R2=R1),
    powmod(M,X,P1,R2,R),!.

exeuclid(_,0,C,_,E,_,C,E).
exeuclid(A,B,C,D,E,F,X,Y):-
    divmod(A,B,G,B1),D1 is C-G*D,F1 is E-G*F,exeuclid(B,B1,D,D1,F,F1,X,Y).
invmod(A,M,R):-exeuclid(A,M,1,0,0,1,R,_),!.

solve(N,R):-
    M=1000000,powmod(M,N,16,1,X),X1 is X-1,invmod(3,M,V),R is 2*X1*V mod M.

start:-f(N,A),(solve(N,R)->(R==A->Str=" ok  ";Str=" no  ");
    write(fail)),write(" "),write(Str),writeln(N->R),fail.
start.

f(5,699050).
f(10, 751850).
f(20, 137450).
f(1237, 689770).
f(12345, 289450).
f(8967452301, 708010).
f(9876543210, 143850).
f(10000000000, 406250).
```
Dockerについてざっくりメモっていく

個人的メモ。
厳密なことは書かない。

# コンテナとハイパーバイザの違い
ハイパーバイザは以下のようなイメージ
![growi-ページ40.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/383c3d68-7b68-4a8d-8fae-a942fb3e12cf.png)

これをAWSのEC2に置き換えるとこうなる
![growi-ページ44.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/6e4f0091-9201-4ff5-829b-1d10efbe8927.png)

コンテナを使うとゲストOSを無くして仮想化環境を用意することが出来る。それぞれのコンテナ（アプリ）はホストのOS（カーネル）を共有して利用している。但し、それぞれのコンテナはNamespace等を使って仮想的に分離されているからお互いに影響を与える可能性は限りなく低い。また、cgroupを使って各コンテナが使用できるホスト側のCPUやメモリ等を制限することも可能。

OSは基本的にLinux系になる（WindowsでもDocker DesktopがあるがWindows Subsystem for Linux（WSL）を使っている時点でLinuxに依存したシステムだと思う。）
![growi-ページ41.drawio (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/295a99e4-da06-4db1-9bec-4b34d637ac53.png)

暴論になるかもだけど、WindowsPCがあって、その上で様々なアプリを動かしたとする。
メモリは32GBを積んでいるPCと想定。
![growi-ページ42.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/60f722d2-fbf7-4eb1-b6a6-9f4fcf35f44e.png)

コンテナ（NamespaceやCgroup）で仮想化するという事はこのアプリ同士を秘匿化（お互いが見えない）しつつ、メモリの使用量をそれぞれのアプリで明確に分けるという事。
![growi-ページ43.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/fe78a9f0-44bc-4b86-a9a9-78b759ffcec6.png)

# コンテナ周りの技術
## volume
コンテナは一度消えてしまうと、コンテナが生成したデータも消えてしまう。
![growi-ページ46.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/39f2579e-8eaa-4194-83d4-355a9efd46bc.png)
volumeはホスト側のストレージ（SSDとかHDD）にDockerのデータを格納するためのやつ。
マウント的なイメージを個人的には持っている。
![growi-ページ47.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/b061cca2-38aa-4092-9fa9-666dc319353f.png)

## network
デフォルトだとコンテナを導入した内部はこうなっている。
仮想的なBridgeを作って、それぞれのコンテナはそれに紐づいている。またこのBridgeはNICとも紐づいている。だから外部ネットからコンテナにアクセスすることが出来たりする。
![growi-ページ48.drawio (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/83e3b0c1-41a7-46dd-b21b-55802f511dc4.png)

こういうことをしたり
![growi-ページ49.drawio (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/1d611ca2-3142-4ec4-8358-5b197a118135.png)

こういうことをすることも可能
Docker SwarmはKubernetesを勉強したいなら先に触ってみるといいと思う。
![growi-ページ50.drawio (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/0ed32125-b3aa-4dc0-86a6-c28ad95cf1d9.png)

## レジストリ
DockerだとDocker Hub。Docker Imageがたくさん置いてある。
本当にざっくりいうなら、ISO的なものがたくさん置いてある場所。

![growi-ページ51.drawio (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/13230365-649c-44dc-ba20-8c1185883a62.png)


https://hub.docker.com/

以下はUbuntuの公式イメージ
docker pull ubuntuを実行するとこいつをローカルに引っ張ってくる

https://hub.docker.com/_/ubuntu

![image (28).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/e5968ca1-d7c6-4ab9-938b-13dc51cb331e.png)

## Dockerfile
イメージを作成するためのレシピ的なヤツ。
イメージのOS、ミドルウェア、アプリを定義する。
デプロイしたコンテナに入って設定を入れ込んで、それをイメージ化することで再利用することも出来るが、本当であればこっちに全部記述したほうがいい。
バージョン管理やドキュメントとしての役割を果たせるようになる。

今後随時更新予定
【VRChat】Udonで自由にポータルを作成する

# はじめに
この記事や、この記事で紹介されているアセットは、**UdonSharpがそれなりに触れる前提で**作成されています。ご了承ください。
この記事では、基本的にインスタンスの指定ができないVRCPortalMarkerを使って、任意のタイミングで指定したインスタンスへのポータルを作成する方法を解説します。

# VRCPortalMarkerについて
ワールドにポータルを置くときに使います。コンポーネントです。
SDKに`VRCPortalMarker.prefab`という名のサンプルがあります。
詳しくは[公式ドキュメント](https://creators.vrchat.com/worlds/components/vrc_portalmarker/)や、Merlin氏が作成した[MerlinVR/UdonSharp](https://github.com/MerlinVR/UdonSharp/wiki/vrchat-api#vrcportalmarker)リポジトリのWikiをご覧ください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3983688/5f508c33-7d50-4478-b61f-b833964cb990.png)
こんな感じです。`World ID`と、なんかいろいろあります。
（「なんかいろいろ」で終わらせたのは、今回は全く触らない機能だからです。）

## not World ID, but Room ID
インスペクターではWorld IDと表示されるので「ワールドIDなんだろうな」と思う方がほとんどだと思いますが、実はこれ、**Room IDです**。U#でも`roomId`でアクセスできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3983688/001c59cb-e6f1-4327-9431-927b91b19ca8.png)
これは実は大きな違いで、Room IDはWorld IDが持っているワールドの情報に加え、**インスタンスの情報を含んでいます**。こいつをUdonでいい感じに作成し、いい感じに突っ込むというのがこの記事の主題です。

# RoomIDのフォーマット
ここで一度RoomIDについて説明しておきます。
RoomIDは、基本的に次のフォーマットになっています。

`[World ID]:[インスタンス ID]~region([リージョンコード])`
| ID/コード        | 説明                                             | 例                                        | 
| ---------------- | ------------------------------------------------ | ----------------------------------------- | 
| ワールドID       | ワールドURLなどにある`wrd_[UUID]`形式のID。      | wrld_beddab1e-fee1-cafe-f00d-ca7c0dd1eca7 | 
| インスタンスID   | インスタンスのID。オーナー情報が入ることもある。 | 12345~hidden(usr_***)                     | 
| リージョンコード | サーバー位置コード。                             | ~region(jp)                               | 

VRChatのウェブサイトのURLはこれを利用したものが多いです。例えば：[vrchat.com/home/world/wrld_beddab1e-fee1-cafe-f00d-ca7c0dd1eca7](https://vrchat.com/home/world/wrld_beddab1e-fee1-cafe-f00d-ca7c0dd1eca7)

# 実装にあたっての落とし穴
上記のフォーマットに基づいてRoomIDを作成し、Udonで`roomId`にセットすればいいように思われますが、実は、通常の方法では、ランタイムでセットした場合**インスタンスIDは無視されます**。しかし、初期値は（なぜか）そのまま反映されるので、`Instantiate`を使用します。[^1]ここでは、Disableしておいたポータルを複製し、Udonで有効化する手法を取ります。

## U#コード
```c#:UdonPortal.cs
[SerializeField] private GameObject portalMarkerPrefab;
private GameObject previousPortal;

private void GenerateNewPortal(string id)
{
    if (Utilities.IsValid(previousPortal))
    {
        GameObject.Destroy(previousPortal);
    }
    GameObject newPortal = GameObject.Instantiate(portalMarkerPrefab, this.gameObject.transform);
    previousPortal = newPortal;
    VRCPortalMarker portal = newPortal.GetComponent<VRCPortalMarker>();
    portal.roomId = id;
    newPortal.SetActive(true);
    portal.enabled = true;
    portal.RefreshPortal();
}
```
Instantiateの仕様上、新しくGameObjectが生成される為、それを適当な変数に保持しておいて次回作成時にDestroyします。`RefreshPortal()`を呼んでいますが必要かどうかは分かりません~~誰か教えて~~。

完全なソースは下のリンクからダウンロードしてご覧ください。

https://nomlas.booth.pm/items/7017374

# バグ？仕様？
紹介した手法で作成したポータルに入ると、なぜか**Publicに飛ばされることがあります**。
これを解決するために、記事を書き、無料配布しておりますので、もし正常動作させることができましたら、どうか**積極的な情報提供**をお願いします。

X（旧Twitter）：https://x.com/nomlasvrc

[^1]: Udonでは`new GameObject()`は禁止されています。
sql

```sql:qiita.rb
CREATE TABLE [your_project:your_dataset.test_all_legacy_types] (
  string_col STRING,
  bytes_col BYTES,
  integer_col INTEGER,
  float_col FLOAT,
  numeric_col NUMERIC,
  bignumeric_col BIGNUMERIC,
  boolean_col BOOLEAN,
  timestamp_col TIMESTAMP,
  date_col DATE,
  time_col TIME,
  datetime_col DATETIME,
  record_col RECORD (
    nested_str STRING,
    nested_int INTEGER
  ),
  repeated_str_col STRING REPEATED
);
```

```sql:qiita.rb
#legacySQL
SELECT
  '文字列' AS string_col,
  b'ABC123' AS bytes_col,
  123 AS integer_col,
  1.23 AS float_col,
  NUMERIC '99999999999999999999999999999.999999999' AS numeric_col,
  BIGNUMERIC '99999999999999999999999999999999999999.99999999999999999999999999999999999999' AS bignumeric_col,
  TRUE AS boolean_col,
  TIMESTAMP('2025-06-07 12:34:56') AS timestamp_col,
  DATE '2025-06-07' AS date_col,
  TIME '12:34:56' AS time_col,
  DATETIME '2025-06-07 12:34:56' AS datetime_col,
  STRUCT('ネスト文字列' AS nested_str, 999 AS nested_int) AS record_col,
  ['要素1', '要素2'] AS repeated_str_col
INTO
  [your_project:your_dataset.test_all_legacy_types_tbl]

```

```sql:qiita.rb
CREATE TABLE [project-id:dataset_id.table_name]
(
  field1 INTEGER REQUIRED "This is a required integer field",
  field2 STRING "This is a nullable string field",
  field3 FLOAT
)
DESCRIPTION "Description of the table"
FRIENDLY_NAME "Friendly Table Name"
EXPIRATION_TIME 1439577000;
```
```sql:qiita.rb
-- 最大値・境界値テスト用のデータを挿入
INSERT INTO `プロジェクトID.データセットID.テーブル名` (
  stringItem,
  byteItem,
  intItem,
  floatItem,
  numItem,
  bigNumItem,
  boolItem,
  timestampItem,
  dateItem,
  timeItem,
  datetimeItem,
  geoItem,
  recordItem,
  rangeItem,
  jsonItem
)
VALUES (
  -- 長い文字列（最大制限テスト）
  REPEAT("最大値テスト", 10),

  -- バイナリデータ（Base64 で 'hello'）
  FROM_BASE64("aGVsbG8="),

  -- INTEGER 最大値
  9223372036854775807,

  -- FLOAT 最大値
  1.79e+308,

  -- NUMERIC の最大値（38桁中 小数点以下9桁）
  NUMERIC "99999999999999999999999999999.999999999",

  -- BIGNUMERIC の最大値（76桁中 小数点以下38桁）
  BIGNUMERIC "5.789604461865809770407157132445255295127E+76",

  -- ブール値（true）
  TRUE,

  -- 最大の TIMESTAMP（9999年）
  TIMESTAMP "9999-12-31 23:59:59.999999 UTC",

  -- DATE の最大値
  DATE "9999-12-31",

  -- TIME の最大値
  TIME "23:59:59.999999",

  -- DATETIME の最大値
  DATETIME "9999-12-31 23:59:59.999999",

  -- GEOGRAPHY（有効範囲の端：経度180・緯度-90）
  ST_GEOGPOINT(180, -90),

  -- RECORD 構造体（ネストされた文字列）
  STRUCT("ネスト1", "ネスト2"),

  -- RANGE<DATE>（有効な日付範囲）
  DATE_RANGE(DATE "2020-01-01", DATE "2021-01-01"),

  -- JSON 文字列
  JSON '{"最大":"テスト", "数値":123}'
);
```
Claude + Blender MCPで写真から3Dモデリング（スマホのパノラマ撮影でやってみた）

# はじめに
:::note info
使用したClaudeプランについて
この記事ではClaude 4のProプランを使用しています。画像とプロンプトの入力制限があるため、Freeプランでは実現が困難です。
:::
本記事では、以下の内容について解説します：

1. Claude + Blender MCPの組み合わせによる写真解析
複数の写真を解析し、3D空間の構造を理解してモデリングコードを生成
1. 写真から3Dモデリングを実現する手法
実際の撮影から3Dモデル生成までの一連の流れ

前提として、[ClaudeからBlenderを操作してモデリングを自動化する方法（Windows11対応）](https://qiita.com/TheRedCatToTheWhiteCat/items/39354e6bcbc04f997ba2)で紹介した環境構築が完了していることを前提とします。

# 動作環境
* Windows 11
* Blender 4.4.3
* Blender MCP 1.1.0
* Claude 4 (Proプラン)
* Python 3.11
* uv 0.7.8

# 撮影の基本手法
効果的な3Dモデリングのための撮影手法を以下に示します：

1. 内周撮影（対象物中心）
    * 原点（対象物）から45度ずつ回転した画像を撮影
    * 推奨枚数：8方向（Claudeの推奨）
1. 外周撮影（対象物を囲む）
    * 原点を焦点とし、45度ずつ回転しながら撮影
    * 推奨枚数：8方向
1. 俯瞰撮影
    * 高い位置からの全体図
    * 空間の全体構造把握に必要
1. 命名規則の重要性
ファイル名に一定の規則を設けることで、Claudeが画像の関係性を理解しやすくなります：
```prompt
例：around_the_origin_h0.JPG
→ 内周_原点_地面の高さ（h0-h3などの高さ情報）
```

# パノラマ撮影による効率化
従来の8方向撮影に代えて、パノラマ機能を使用することで大幅な効率化が可能です。
* 1枚の画像で内周の完全情報を取得
* 空間の連続性を正確に把握
* 撮影時間の大幅短縮
* 撮影ミスの削減

# 使用した画像(全11枚)
パノラマ画像(2枚)
1. 原点から360度パノラマ撮影【低位置から】
1. 原点から360度パノラマ撮影【目線レベルから】

外周画像(8枚) 3-10. 外周を45度刻みで撮影【目線レベル】
俯瞰画像(1枚) 11. 二階から撮影した俯瞰図
![photofolder.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4103380/7367b2bc-3399-43c2-bbdb-d6fa304e3ff9.png)

ファイル名に命名規則を与えておくとClaudeは対応しやすいそうです。
例：around_the_origin_h0.JPG -> 内周_原点_地面の高さ(h0-h3などで理解できるとのこと)

# 動作確認
```prompt
Blenderとアップロードした画像をもとに3Dモデリングを行ってほしいです。

【撮影対象の説明】
アップロードした最後の画像(overview_h3.jpg)にある左側の木が、今回モデリングする原点となる場所です。

【画像の構成】
- 1,2枚目：高さの異なる内周パノラマ画像（中央の木が原点）
- 3-10枚目：同一高さの外周画像（8方向から撮影）
- 11枚目：俯瞰図（全体の空間構造把握用）

【期待する出力】
木の形状、周辺地形、空間的な配置関係を考慮した3Dモデルを生成してください。
```

生成結果
<iframe width="560" height="315" src="https://www.youtube.com/embed/58_6-3BntoU?si=ejpmpHSB7nlCpQv6" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

# まとめ
写真を使ったClaudeとBlenderによる3Dモデリングは、従来の手動モデリングと比較して大幅な時間短縮を実現できます。特にパノラマ撮影の活用により、撮影効率と品質の両立が可能になりました。