OmniAICreator/Qiita-1.07M huggingface dataset:
C/C++/C# における Loop Keywords

# C/C++/C# における Loop 文のキーワード解説

プログラミングにおいて、ループ処理は非常に重要な要素です。C、C++、C# では、ループ内で使われる特定のキーワードがあり、処理の流れを制御するのに役立ちます。本記事では、`return`、`break`、`continue` の3つのキーワードについて詳しく解説します。

## 1. `return`：関数を終了する
`return` は、関数の実行を即座に終了し、呼び出し元に制御を戻すためのキーワードです。ループの中で `return` が呼ばれると、ループの処理だけでなく、関数全体の実行も終了します。

### 使用例
```cpp
#include <iostream>

void exampleFunction() {
    for (int i = 0; i < 5; i++) {
        if (i == 3) {
            std::cout << "Returning at i = " << i << std::endl;
            return; // 関数の実行を終了
        }
        std::cout << "i = " << i << std::endl;
    }
    std::cout << "This line will not be executed if i == 3" << std::endl;
}

int main() {
    exampleFunction();
    std::cout << "Back in main function" << std::endl;
    return 0;
}
```
### 実行結果
```
i = 0
i = 1
i = 2
Returning at i = 3
Back in main function
```
`return` が呼ばれた時点で `exampleFunction` の実行が終了し、それ以降の処理は行われません。

## 2. `break`：ループを抜ける
`break` は、現在のループ（`for`、`while`、`do-while` など）の実行を途中で終了し、ループの外に制御を移します。

### 使用例
```cpp
#include <iostream>

int main() {
    for (int i = 0; i < 5; i++) {
        if (i == 3) {
            std::cout << "Breaking at i = " << i << std::endl;
            break; // ループを抜ける
        }
        std::cout << "i = " << i << std::endl;
    }
    std::cout << "Loop finished" << std::endl;
    return 0;
}
```
### 実行結果
```
i = 0
i = 1
i = 2
Breaking at i = 3
Loop finished
```
`i == 3` になった時点で `break` が呼ばれ、ループを終了して `Loop finished` が出力されます。

## 3. `continue`：次のループの繰り返しに進む
`continue` は、現在のループの処理をスキップし、次の繰り返しに進むためのキーワードです。ループ自体を終了するわけではありません。

### 使用例
```cpp
#include <iostream>

int main() {
    for (int i = 0; i < 5; i++) {
        if (i == 3) {
            std::cout << "Skipping i = " << i << std::endl;
            continue; // 残りの処理をスキップして次のループへ
        }
        std::cout << "i = " << i << std::endl;
    }
    std::cout << "Loop finished" << std::endl;
    return 0;
}
```
### 実行結果
```
i = 0
i = 1
i = 2
Skipping i = 3
i = 4
Loop finished
```
`i == 3` のとき `continue` が実行され、それ以降の処理（`std::cout << "i = " << i << std::endl;`）はスキップされます。ただし、ループは継続し、`i = 4` の処理は実行されます。

## まとめ
| キーワード | 役割 |
|------------|---------------------------|
| `return`   | 関数を途中で終了する |
| `break`    | ループを途中で終了する |
| `continue` | ループの現在の処理をスキップし、次の反復へ進む |

これらのキーワードを適切に使い分けることで、プログラムの制御を柔軟に行うことができます。特に、無限ループの制御やエラーハンドリングにおいて `break` や `return` は非常に便利です。
Cannot determine the organization name for this 'dev.azure.com' remote URLの解決

SourceTreeを使って、DevOpsにプッシュしようとしたら、急にできなくなってしまったので、その解決法のメモ書き

- エラー内容

    ```
    git -c diff.mnemonicprefix=false -c core.quotepath=false --no-optional-locks push -v origin feature/addMixDisease:feature/addMixDisease
    fatal: Cannot determine the organization name for this 'dev.azure.com' remote URL. Ensure the `credential.useHttpPath` configuration value is set, or set the organization name as the user in the remote URL '{org}@dev.azure.com'.
    fatal: Cannot determine the organization name for this 'dev.azure.com' remote URL. Ensure the `credential.useHttpPath` configuration value is set, or set the organization name as the user in the remote URL '{org}@dev.azure.com'.
    fatal: Authentication failed for 'https://dev.azure.com/hoge'
    Pushing to https://dev.azure.com/hoge
    エラー終了しました。エラーの内容は上記をご覧ください。
    ```

- 試したこと
    - SourceTreeを閉じる
    - コマンドプロンプトで以下のコマンドを実行
        `git config --global credential.useHttpPath true`
    - SourceTreeを開いてプッシュ


- GPTに聞いた
    ```
    credential.useHttpPath true を設定すると？
    この設定を有効にすると、Gitは URLのパスも認証情報のキーとして扱う ようになる。
    
    つまり、認証情報をキャッシュするときに リポジトリごと に記録するようになるんや。
    
    ✅ 設定前（デフォルト）
    
    dev.azure.com だけを認証情報として保存
    組織やリポジトリが異なっても同じ認証情報を使おうとする
    結果的に 組織名が見つからず認証エラー になることがある
    ✅ 設定後（true）
    
    https://dev.azure.com/my-org/my-project/_git/my-repo のように フルパスでキャッシュ
    各リポジトリで 正しい認証情報を使う
    Azure DevOpsでの認証エラーを防ぐ
    ```

    複数組織を追加している場合に正しいパスをキャッシュするような設定ってことかな。
GKEのCloud NAT設定：指定するサブネットとIPマスカレードについて

## 概要

Cloud NAT を設定する際に送信元GKEサブネットをすべてのサブネットを対象とせず、カスタムで限定したい場合にプライマリーIP範囲かセカンダリーIP範囲のどちらを設定すれば良いかについて迷ったので、GKEのIPマスカレードとCloud NAT の送信元GKEサブネットの関連性を含めて設定解を説明します。

## GKEのIPマスカレードとは

GKEのIPマスカレード（IP masquerade）とは、Podがクラスタ外のネットワークに通信する際、ノードIPアドレスにSNATする仕組みです。

## Cloud NAT とは

Cloud NATは、Google Cloudが提供するフルマネージドのNAT（Network Address Translation）サービスです。　Google Cloud 内のプライベートIPアドレスのみを持つVM、GKEノードが、インターネットに通信する際、Cloud NATで割り当てたIPにSNATして通信できるようにする仕組みです。

## Cloud NATの設定

Cloud NATを設定する際、送信元となるGKEサブネットの範囲を指定する必要があります。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3580319/7328eec0-7332-48d1-85a7-69fef50d56bb.png)

GKEのPodにセカンダリーIP範囲を割り当てている場合、Cloud NATの設定でプライマリとセカンダリのどちらを指定すべきかを検証しました。

GKEのIPマスカレードはデフォルトで有効になっています。

その場合は、プライマリの指定のみでCloud NATを利用したインターネット通信ができます。つまり、インターネットに通信する際は、

`Pod (セカンダリIP)` → `[SNAT]` → `Node (プライマリIP)` → `[SNAT]` → `Cloud NAT IP` → インターネット

という風にアドレス変換されるため、Cloud NATは、GKEノードのプライマリIP範囲を指定する必要があります
仮にセカンダリのみを指定するとインターネット接続はできません。

一方、IPマスカレードを無効化した場合は、Pod用のセカンダリIP範囲の指定によってインターネット通信ができます。同様にプライマリのみを指定しても接続はできません。

念の為の情報ですが、GKEのIPマスカレードに関してGKE Datapane V1はiptablesベース、V2はeBPFベースとなり仕組みが異なりますが、Cloud NATの設定について上記で差異はありません。


## 検証方法

Step 1 :  プライベートGKEクラスターを作成 (片方はIPマスカレードを無効化)

Step 2 :  Cloud NATの作成

- NATマッピングのサブネット範囲指定でカスタムを選択
- プライマリのみを指定 or セカンダリのみ指定

Step 3 :  検証用のPodを起動し、インターネット接続を試みてIPチェック

```zsh
gcloud container clusters describe my-cluster --region asia-northeast2 
```

```zsh
kubectl run -it busybox --image=busybox --restart=Never -- sh
```

```bash
# wget -qO- http://ifconfig.me
```

正常に設定されている場合はインターネットに接続でき、Cloud NATに割り当てたIPアドレスが出力されます。

Step2 と Step3 を繰り返してそれぞれのパターンの動作確認を行いました。


## まとめ

- Cloud NATのソースサブネット設定時に、GKEのIPマスカレードが有効な場合はノードのプライマリIP を指定する必要がある

- IPマスカレードを無効化した場合、PodのセカンダリIPがそのままCloud NATを通るため、Cloud NATの送信元サブネットの範囲にセカンダリを指定する必要がある

以上です。
Mavenでフロントエンドライブラリを統一管理しよう

近年のWeb開発では、フロントエンドライブラリの管理が重要な課題の一つとなっています。適切に管理されていないと、ライブラリの競合やバージョンの不整合が発生し、システムの安定性が損なわれる可能性があります。

本記事では、フロントエンドライブラリの管理方法と、その統一管理をMavenで行うメリットについて解説します。

### 現状の課題：
フロントエンドライブラリの管理が分散している多くのプロジェクトでは、歴史的な経緯により、以下のようなバラバラな方法でフロントエンドライブラリが管理されています。

#### ① 外部CDNを直接参照するケース
```
<script src="https://gyrocode.github.io/jquery-datatables-checkboxes/1.2.12/js/dataTables.checkboxes.min.js"></script>
```
:::note alert
問題点
・外部サイトの障害に依存
 　→ 参照元のサイトがダウンすると、システムも影響を受ける。
・バージョンが勝手に更新されるリスク
　→ 予期せぬ変更により、動作が不安定になる可能性。
:::
 #### ② ローカルに直接配置するケース
```
<link rel="stylesheet" th:href="@{/dist/plugins/data-tables/datatables.min.css}" />
```
:::note alert
問題点
・手動管理の負担が大きい
　→ 各環境での配置ミスが発生しやすく、管理が煩雑。
・バージョンの統一が困難
　→ 誰かが最新版をローカルに追加しても、他の環境に反映されていないことがある。
:::
### 解決策：Mavenでフロントエンドライブラリを統一管理する
:::note info
メリット
・外部サイトに依存しない
　→ CDNを使わず、すべてのライブラリをプロジェクト内で一元管理できるため、外部サイトの障害に左右されない。
・バージョン管理が簡単
　→ Mavenの pom.xml でバージョンを指定することで、全員が同じバージョンのライブラリを利用できる。
・環境ごとの差異をなくせる
　→ 手動でファイルを配置する必要がなくなり、どの環境でも同じライブラリを確実に取得できる。
:::

### 具体的なMaven管理の方法
#### ① 依存関係を pom.xml に追加
```
<dependency>
    <groupId>org.webjars</groupId>
    <artifactId>datatables</artifactId>
    <version>1.10.21</version>
</dependency>
```

#### ② HTMLからMaven管理のリソースを読み込む
```
<!-- DataTablesのCSS -->
<link rel="stylesheet" th:href="@{/webjars/datatables/css/jquery.dataTables.min.css}" />

<!-- DataTablesのJavaScript -->
<script th:src="@{/webjars/datatables/js/jquery.dataTables.min.js}"></script>
```

フロントエンドの管理をMavenに統一し、より安定した開発環境を構築しましょう！ 🚀
フリーランスエンジニアが案件を安定確保する戦略【営業・単価UP・ポートフォリオ】

# フリーランスエンジニアが案件を安定確保する戦略【営業・単価UP・ポートフォリオ】

## 📢 はじめに
フリーランスエンジニアとして成功するためには、案件を安定して獲得する仕組みが必要です。  
本記事では、営業が苦手な人でも安定して案件を獲得するための戦略を解説します。

---

## ✅ 仕事が途切れない3つの案件獲得ルート
📢 **1. エージェントを活用する** → 確実だが単価は低め  
📢 **2. 直営業（企業DM・紹介）** → 高単価だが営業が必要  
📢 **3. SNS・ブログで案件を獲得する** → 継続的な案件が舞い込む  

---

## ✅ 直営業で単価UPを実現する方法
📢 **企業の採用ページを活用し、直接アプローチ**  
📢 **DMやメールを営業用テンプレートで効率化**  
📢 **価格交渉ではなく、価値提案を意識する**  

---

## ✅ 価値を伝えるポートフォリオの作り方
📢 **スキルの羅列ではなく「成果」を伝える**  
📢 **「◯◯の課題を解決し、売上20%UP！」と明確にする**  
📢 **具体的な成功事例を掲載すると効果抜群**  

🔥 **この戦略を実践すれば、フリーランスでも仕事が途切れなくなります！**
CloudFlareを導入したWebサイトにBasic認証を掛ける方法

# 背景
Webサイトにクラウドフレアを導入した。

# 要望
コントロールパネルからではなく、Apacheの設定でBasic認証を導入したい

# 方法
```apache
# CloudFlareからの実際のクライアントIPを取得
SetEnvIf CF-Connecting-IP . CFIP=$0

# Basic認証の設定
AuthUserFile "/var/www/html/.htpasswd"
AuthName "Please enter your ID and password"
AuthType Basic
Require valid-user

# キャッシュ制御
<IfModule mod_headers.c>
    Header set Cache-Control "no-cache, no-store, must-revalidate"
    Header set Pragma "no-cache"
    Header set Expires 0
</IfModule>

# オリジナルのIPアドレスをチェック
SetEnvIf CF-Connecting-IP "192\.10\.123\.[0-9]{1,3}" hoge

# アクセス制御
Order Allow,Deny

# 環境変数による制御
Allow from env=hoge

# 直接アクセスを許可
Allow from 192.01.123.0/24
```
Git完全攻略チートシート｜基本操作から高度なテクニックまで

# はじめに

Gitは開発者にとって欠かせないバージョン管理システムです。本記事では、よく使うGitコマンドをチートシート形式で紹介します。

## 基本操作

### Gitの設定
```sh
# ユーザー名とメールアドレスの設定
git config --global user.name "Your Name"
git config --global user.email "your.email@example.com"

# 設定の確認
git config --list
```

### リポジトリの作成とクローン
```sh
# 新しいリポジトリの作成
git init

# 既存のリポジトリをクローン
git clone <repository_url>
```

### ステージングとコミット
```sh
# 変更をステージング（追加）
git add <file>

# すべての変更をステージング
git add .

# コミットを作成
git commit -m "コミットメッセージ"
```

## ブランチ操作

### ブランチの作成と切り替え
```sh
# ブランチの作成
git branch <branch_name>

# ブランチの切り替え
git checkout <branch_name>

# 作成と同時に切り替え
git checkout -b <branch_name>
```

### ブランチの統合（マージ）
```sh
# ブランチを現在のブランチにマージ
git merge <branch_name>
```

### ブランチの削除
```sh
# ローカルブランチの削除
git branch -d <branch_name>

# リモートブランチの削除
git push origin --delete <branch_name>
```

## リモートリポジトリ操作

### リモートの登録と確認
```sh
# リモートリポジトリの追加
git remote add origin <repository_url>

# リモートリポジトリの確認
git remote -v
```

### プッシュとプル
```sh
# リモートにプッシュ
git push origin <branch_name>

# 最新の変更を取得
git pull origin <branch_name>
```

### フェッチとマージ
```sh
# リモートの変更を取得（自動でマージしない）
git fetch origin

# 取得した変更をマージ
git merge origin/<branch_name>
```

## 変更の管理

### 変更の確認
```sh
# 変更の一覧を確認
git status

# 変更の詳細を確認
git diff
```

### 変更の取り消し
```sh
# ステージング前の変更を取り消し
git checkout -- <file>

# ステージング済みの変更を取り消し
git reset HEAD <file>
```

## ログの確認
```sh
# コミットログを表示
git log

# 簡潔なログ表示
git log --oneline
```

## その他の便利なコマンド
```sh
# 最新のコミットを上書き（要注意）
git commit --amend

# コミット履歴を操作（要注意）
git rebase -i HEAD~n

# 強制プッシュ（慎重に）
git push origin <branch_name> --force
```

## 高度な操作

### 一時的に変更を退避（stash）
```sh
# 作業中の変更を一時保存
git stash

# スタッシュ一覧を表示
git stash list

# 最新のスタッシュを適用
git stash apply

# スタッシュを削除
git stash drop
```

### 特定のコミットを別のブランチに適用（cherry-pick）
```sh
# 指定したコミットを現在のブランチに適用
git cherry-pick <commit_hash>
```

### バグ修正のためのバイセクト（bisect）
```sh
# バグのあるコミットを特定
git bisect start
git bisect bad   # 現在のバージョンをbadとする
git bisect good <commit_hash>  # 既知の正常なバージョンを指定
```

### リファレンスログの確認（reflog）
```sh
# ローカルの操作履歴を表示
git reflog
```

## まとめ
Gitの基本的な操作をチートシートとしてまとめました。日々の開発で活用し、効率的にバージョン管理を行いましょう！
開発初心者がFlutter環境構築でつまずいたポイントと解決方法

## GitHubクローン & Flutter環境構築でつまずいたポイントと解決方法

### はじめに

Flutterでのアプリ開発を始めるにあたり、最初の関門となったのが **GitHubのクローン** と **Flutterの環境構築** だった。

GitHub自体は知っていたものの実際に使ったことはなく、Flutterも完全に未経験。特に環境構築ではエラーの連続で、試行錯誤の繰り返しとなった。

本記事では、初心者目線で **GitHubクローン & Flutter環境構築で発生したエラー** とその **解決方法** について詳しく解説する。

---

## 1. GitHubのクローン

### 手順

1. GitHubリポジトリのURLを取得
2. ターミナルまたはCursorで `git clone <リポジトリURL>` を実行
3. ローカルにプロジェクトが作成されることを確認

### つまずいたポイント & 解決策


#### ✅ Gitがインストールされていなかった
**問題:** `git clone` を実行すると `command not found` エラーが発生。

**解決:** Gitをインストール。
```bash
# Macの場合
brew install git

# Windowsの場合（公式サイトからインストール）
https://git-scm.com/downloads
```

GitHub Desktopを使うと、GUIで簡単にクローンできるため、初心者にはおすすめ。

---

## 2. Flutterの環境構築

### 手順

1. Flutter SDKをダウンロード & 解凍
2. 環境変数を設定
3. `flutter doctor` を実行して環境を確認
4. Android Studio & 必要なSDKをインストール

### つまずいたポイント & 解決策

#### ✅ ダウンロードフォルダにインストールしてしまい、パスが迷子
**問題:** 途中でフォルダを移動させたため、`flutter doctor` がFlutterを認識できなくなった。

**解決:** 一度Flutterを削除し、ユーザーフォルダに再インストール。
```bash
# 環境変数の設定を再確認
export PATH="$PATH:/Users/your_user/flutter/bin"
```

#### ✅ JDKのバージョンによるエラー
**問題:** Java 21を使用していたが、GradleやAGPのバージョンとの組み合わせでエラーが発生。

**解決:** Java 17にダウングレードし、Gradle設定で指定。
```bash
export JAVA_HOME="/Library/Java/JavaVirtualMachines/jdk-17.jdk/Contents/Home"
```
または `gradle.properties` に以下を追加。
```properties
org.gradle.java.home=/Library/Java/JavaVirtualMachines/jdk-17.jdk/Contents/Home
```

#### ✅ Android Studioの埋め込みJDKが問題だった
**問題:** `flutter doctor` ではJava 17が設定されていたが、実際にはAndroid Studioの埋め込みJDK（Java 21）が使用されていた。

**解決:** Android Studioの `gradle.properties` に明示的にJDKのパスを指定。

---

## まとめ

- GitHubのクローンは **SSHキーを設定する** ことでスムーズに。
- Flutterの環境構築では **ダウンロード場所とパス設定に注意**。
- Javaのバージョンは **GradleやAGPと互換性のあるものを選択**。
- Android StudioのJDK設定を確認し、`gradle.properties` で指定すると確実。

開発を進める上で環境構築は避けて通れないが、つまずいた際はエラーメッセージをよく読んで対処するのが大切。初心者の方の参考になれば幸い！
Flutterのcodelabを実際にやってみた感想

## はじめに
Flutterの習熟の一環として[codelab](https://docs.flutter.dev/codelabs)の内容に取り組んでいるので、それぞれのセクションで感じたことをまとめてみた。取り組むたびに随時更新していく予定です。予定は予定です！（動画のワークショップは後回しにしてます）
事前にDartとFlutterのドキュメントを上から少しだけざっと読んだ程度＋αの理解度で取り組んでいます。（画像参照）
**読んだ箇所（写ってる範囲、公式HPから切り抜きました、手抜きです）**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3301848/d5201722-4898-46f8-b1ad-e4b018dcee44.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3301848/3d5c8d31-3c23-4ce8-be72-5eeae0e6ab6f.png)

## 初めての Flutter アプリ
実施日：2025年1月末か2月上旬（少し前であやふやです）

[初めての Flutter アプリ](https://codelabs.developers.google.com/codelabs/flutter-codelab-first?hl=ja#0)

状態管理の基本を学べる。
テーマを利用して見た目を整える方法の基礎を学べた。
高度なバージョンはまだまだ理解が難しい箇所もあった。
## Dart のパターンとレコードを使ってみる
実施日：2025年2月20日（この期間なにしてんのよ...）

[Dart のパターンとレコードを使ってみる](https://codelabs.developers.google.com/codelabs/dart-patterns-records?hl=ja#0)

パターンを使って簡潔に記述する方法を理解できた。変数や明示的なチェックを省き、尚且つ予期しないエラーの発生を減らせると思う。switch式の存在を知らなかったのでよい勉強になった。
また、オブジェクトにパターンを適用して、要素の異なるオブジェクトをまとめて扱える方法は実用的だと感じた。（うまく説明できない。）
main.dartでは表示に関する内容が、data.dartではjsonの処理に関する内容が扱われていて、「関心の分離」の良いサンプルになっていると感じた。このセクションの流れのように、最初は変数で明記して段階的に変えていけば自分でも実現できそう。
## レイアウトのエラーをデバッグする方法
実施日：2025年2月20日（この期間なにしてんのよ...）

[How to debug layout issues with the Flutter Inspector](https://medium.com/flutter/how-to-debug-layout-issues-with-the-flutter-inspector-87460a7b9db)

Dart DevTools を使ってアプリのレイアウトのエラーを解決する方法を紹介している。記事が2020年に作成されているので、一部内容を再現できないものがあった。ちなみに、公式が用意したものではなく、有志の方が作成した記事らしい。
WindowsのVScodeでは、DevToolsはアプリ起動後の操作用アイコンリストから起動できる。
![DevToolsHere.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3301848/e6d5d700-76c6-476f-95af-b7f590079efd.png)

例1・2・3を通してよくあるレイアウトの問題を解決していく。例1は再現できるか怪しいので飛ばした。
肝は「子ウィジェットの制約は親ウィジェットから引き継ぐ」ということ。
明示的に制約を与えない限り、高さが無限になったり0になったりするウィジェットがある。これらに高さの制約を与える方法として、`Expanded`や`SizeBox`で包むことによって解決していた。
`Column`や`Row`などの実際に内容を表示するウィジェットを他のウィジェットの子にすることで、意図した通りの見た目にするための制約を課す感じになるのかな。
DevToolsの見るべきポイントが紹介されていたので、取り上げられていない事例に遭遇した際も一つずつ原因を追っていくことで自力でエラーを解消できるようにしたい。
Oracle APEXにおけるアプリケーション作業用のコピーの作成方法

# 1.はじめに
Oracle APEX (Application Express) は、データベース中心のWebアプリケーションを簡単に作成・管理できるローコード開発プラットフォームです。
開発中に、既存のアプリケーションに影響を与えずに新機能の追加やバグ修正を行いたい場合、作業用コピー機能が非常に有用です。


# 2.作業用コピーとは
作業用コピーとは、既存のアプリケーションの特別なコピーを作成し、そのコピー上で変更を行い、後でメインの開発アプリケーション（メイン・アプリケーション）にその変更をマージできる機能です。これにより、開発者は安全に新しい機能の開発やテストを行うことができます。

# 3.作業用コピーの利点
安全な開発環境：メイン・アプリケーションに直接影響を与えずに変更を試すことができます。
チーム開発の効率化：複数の開発者がそれぞれの作業用コピーで作業し、後で変更を統合できます。
選択的なマージ：作業用コピーとメイン・アプリケーションの差分を確認し、必要な変更のみをマージできます。


# 4.作業用コピーの作成手順
作業用コピーを作成するには、以下の手順を実行します。

アプリケーション・ビルダーにアクセス：Oracle APEXのアプリケーション・ビルダーにログインします。
対象のアプリケーションを選択：作業用コピーを作成したいアプリケーションを選びます。
作業用コピーの作成：
アプリケーションのホームページで、**「作業用コピーの作成」**オプションを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3505194/be1c8d63-8a85-440a-9dad-b8937126f332.png)

作業用コピーに適切な名前を付け、作成を確認します。
これにより、選択したアプリケーションの作業用コピーが作成されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3505194/82d84295-09e5-4857-be0a-414042cdfbfa.png)


# 5.作業用コピーの管理とマージ
作業用コピーでの変更が完了したら、以下の手順でメイン・アプリケーションにマージします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3505194/8239fb95-d57a-4f0c-8be8-d7df57c6e721.png)


変更の比較：
作業用コピーとメイン・アプリケーションの差分を表示し、どの変更をマージするかを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3505194/ee219a7c-25be-4720-acf2-cb7bf9059498.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3505194/8eb18a24-c1e1-4527-a724-3d2b63b27723.png)

マージの実行：
選択した変更をメイン・アプリケーションにマージします。
必要に応じて、メイン・アプリケーションから作業用コピーへの変更のマージも可能です。
このプロセスにより、開発者は安全かつ効率的に変更を統合できます。 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3505194/63d11f95-43f3-46a6-823b-16e73625def7.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3505194/b68519b0-46ff-41ac-929c-bf8d536e8b94.png)

# 6. 注意点
サポートされていないコンポーネント：翻訳、テーマ、テーマ・テンプレート、サポート・オブジェクト、アプリケーションのプロパティ、ワークスペースレベルのコンポーネントなどは、自動マージがサポートされていません。これらの変更は手動で適用する必要があります。
作業用コピーの制限：作業用コピーの中にさらに作業用コピーを作成することはできません。また、作業用コピーで削除したコンポーネントは、メイン・アプリケーションで手動で削除する必要があります。 

# 7. まとめ
Oracle APEXの作業用コピー機能を活用することで、開発者は安全かつ効率的にアプリケーションの開発やテストを行い、チーム開発の生産性を向上させることができます。適切に管理し、注意点を守ることで、メイン・アプリケーションへの影響を最小限に抑えながら開発を進めることが可能です。
そうだ、アウトプットをしよう

# はじめに
この度、Qiitaに投稿をしてアウトプット力を高めよう！という意気で登録しました。
まずはその踏み出す一歩目として目標をこの記事に書き記しておきます。
（アウトプット不慣れなので文脈が変なのはご了承ください）

# こんな人です
製造系の会社に約10年間勤務し、色々あり地方のSES企業にデータサイエンティストとして転職しました。
現在は、新米として簡単なデータ整理をしています。
プログラミングに関しては、C言語やhtmlとCSS等の基本しか触れていません。

# 目標
:::note info
・短期目標（3ヶ月）
SIGNATEの練習問題コンペ等に参加しPythonの基礎を身につける

・中期目標（6ヶ月）
本格的なコンペに参加する
GitHubで個人開発をする

・長期目標（1年）
現場で頼られるデータサイエンティストになる
キャリアアップと副業で収入アップ
:::

これからQiitaを通じて様々な投稿をしていきたいと考えています。
どうぞよろしくお願いします。
【図解】プロトタイプチェーンをなるべくシンプルに分かりやすくまとめてみた

複雑で理解しにくいJavaScriptのプロトタイプチェーンを、シンプルな図にしてイメージしやすくしよう！という試みです。
今回は、組み込みのコンストラクタ関数Arrayを例にしています。
## 前提
| 用語 | 説明 |
|:--|:--|
| [[prototype]]  | オブジェクトの継承元を指す隠しプロパティ。これにより、オブジェクトはプロトタイプチェーンを通じて親オブジェクトのプロパティやメソッドを継承する。Object.getPrototypeOf(obj) や \_\_proto\_\_ プロパティでアクセスできる。
|  prototype |   コンストラクタ関数が持つプロパティ。コンストラクタ関数のprototypeに設定したオブジェクトは、自身のインスタンス生成時に[[prototype]]に格納される。|
|  コンストラクタ関数 |  ObjectやArrayなど、newでインスタンスを生成できる関数のこと。 |

## プロトタイプチェーン図解
![プロトタイプチェーン.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4015340/4f490ed5-0bf8-400f-a924-619443e12ee4.jpeg)

* Array.prototypeは[[prototype]]にObject.prototypeを持つ。
* Object.prototypeは[[prototype]]がnull。つまりプロトタイプチェーンの終着点。
* コンストラクタ関数Arrayのインスタンスであるnew Array()は、Array.prototypeを[[prototype]]に持つため、プロトタイプチェーンによってArray.prototypeとObject.prototypeのプロパティ&メソッドを使用できる。
* コンストラクタ関数ObjectやArrayは関数オブジェクトであるため、コンストラクタ関数Functionのインスタンスとして生成される。そのため、自身(ObjectやArray)の[[prototype]]にはFunction.prototypeを持つ。これは自身のprototypeが持つ[[prototype]]とは別物なことに注意。

## まとめ
* プロトタイプチェーンとは、オブジェクトが呼び出されたプロパティやメソッドを持っていない場合に、[[Prototype]] をたどって親のオブジェクトを探索する仕組み。
例：new Array(1,2,3).toString() では、まずtoStringがnew Array(1,2,3).\[[prototype]](つまりArray.prototype)にあるかチェックされる。そこになければArray.prototype.\[[prototype]](つまりObject.prototype)にあるかチェックされる。toStringはObject.prototypeのメソッドなので、ここで見つかり実行される。

* ArrayやObject等のコンストラクタ関数のprototypeプロパティに設定したオブジェクトが、インスタンスの隠しプロパティ[[prototype]]に格納される。
例：Array.prototypeはnew Array().[[prototype]]に格納される。
【Python】VSCodeでpytestを使ってテストコードを実行する方法

# はじめに

Pythonでの開発では、テストの自動化が重要です。今回は、**VSCode**上で**pytest**を使ってテストを実行する方法を解説します。

初心者向けに、環境構築から基本的なテストの実行方法まで詳しく説明します！

---

## 1. 環境構築

### (1) Pythonのインストール
Pythonがインストールされていない場合は、以下の公式サイトからインストールしてください。
👉 [Python公式サイト](https://www.python.org/downloads/)

インストール後、以下のコマンドでバージョンを確認します。

```sh
python --version
```

または（環境によっては`python3`の場合もあります）

```sh
python3 --version
```

---

### (2) VSCodeの拡張機能をインストール
VSCodeでPython開発を快適にするため、以下の拡張機能をインストールしましょう。

1. **Python Extension for Visual Studio Code**
   - VSCodeの拡張機能 (`Ctrl + Shift + X`) で `Python` を検索し、`Microsoft`製の拡張機能をインストール

2. **Python Test Explorer for Visual Studio Code（任意）**
   - `Python Test Explorer` をインストールすると、GUIでテストを実行可能

---

### (3) 仮想環境の作成（推奨）

プロジェクトごとに仮想環境を作成すると、依存関係を管理しやすくなります。

```sh
python -m venv venv
```

仮想環境を有効化します。

- Windows（PowerShell）:
  ```sh
  .\venv\Scripts\Activate
  ```
- macOS / Linux:
  ```sh
  source venv/bin/activate
  ```

---

### (4) `pytest` のインストール
仮想環境を有効化した状態で、以下のコマンドを実行します。

```sh
pip install pytest
```

インストール確認:

```sh
pytest --version
```

---

## 2. 簡単なテストコードを書く

### (1) テスト対象の関数を作る
まず、`math_functions.py` というファイルを作成し、以下の関数を定義します。

```python
# math_functions.py
def add(x, y):
    return x + y

def multiply(x, y):
    return x * y
```

---

### (2) テストコードを書く
次に、`test_math_functions.py` を作成し、テストコードを書きます。

```python
# test_math_functions.py
from math_functions import add, multiply

def test_add():
    assert add(2, 3) == 5
    assert add(-1, 1) == 0
    assert add(0, 0) == 0

def test_multiply():
    assert multiply(2, 3) == 6
    assert multiply(-1, 1) == -1
    assert multiply(0, 10) == 0
```

✅ **ポイント**
- ファイル名は `test_` で始める（`pytest` は `test_*.py` を自動的に探す）
- `assert` を使って期待値と実際の値を比較する

---

## 3. `pytest` を使ってテストを実行

ターミナルで以下を実行。

```sh
pytest
```

特定のテストファイルだけを実行したい場合は：

```sh
pytest test_math_functions.py
```

✅ **成功した場合の出力例**

```
============================= test session starts =============================
collected 2 items

test_math_functions.py ..                                         [100%]

============================== 2 passed in 0.12s ==============================
```

❌ **失敗した場合**
エラーメッセージが表示されるので、修正して再実行。

---

## 4. VSCodeで`pytest`を実行する方法

### (1) Python 拡張機能を使う

1. **テストの自動検出を有効化**
   - VSCodeの左側のテストアイコン（🧪）をクリック
   - `Configure Python Tests`（「Python テストの構成」）をクリック
   - `pytest` を選択し、`tests`（またはプロジェクトのテストフォルダ）を選択

2. **テストを実行**
   - `Run Test` ボタンをクリック

---

### (2) `Python Test Explorer` 拡張機能を使う（GUI）

1. `Python Test Explorer` をインストール
2. **テストの自動検出**を有効にする
3. `Test Explorer` タブからGUIでテストを実行＆結果を確認

---

## 5. トラブルシューティング

✅ **`pytest`が見つからない場合**
- 仮想環境が有効になっているか確認
- `pytest`がインストールされているか確認 (`pip list | grep pytest`)

✅ **テストが認識されない場合**
- `pytest.ini` を作成し、以下を設定すると改善することがあります。

```ini
# pytest.ini
[pytest]
python_files = test_*.py
python_functions = test_*
```

---

## まとめ

✅ **手順のおさらい**
1. **環境構築**（Python + VSCode + `pytest` をインストール）
2. **テストコードを書く**（`assert` を使って期待値をチェック）
3. **`pytest` でテスト実行**（CLIまたはVSCodeのGUIから実行）

これで、VSCode上で`pytest`を使ってテストを実行できるようになりました！🎉

もっと学びたい場合は、公式ドキュメントもチェックしてみてください。
👉 [pytest公式ドキュメント](https://docs.pytest.org/en/latest/)

この記事が役に立ったら、いいねやシェアをお願いします！😊
Nginx配置

```nginx
server {
    listen 80 default_server;
    server_name kuanghaoran.com; #指向域名
    
    # 指定网站根目录
    root /www/wwwroot/dist;
    index index.html;

    # 处理前端 SPA（单页面应用）指向/index.html，解决刷新404
    location / {
        try_files $uri $uri/index.html /index.html;
    }

    # 代理 API 请求到后端 解决跨域问题
    location /api {
        proxy_pass http://kuanghaoran.com:8000;
        proxy_set_header Host $proxy_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        
        proxy_buffering off;
        proxy_set_header Connection ""; #解决前端 set-cookies🍪不生效问题
    }

    # 日志配置
    access_log /www/wwwlogs/kuanghaoran.com.log;
    error_log /www/wwwlogs/kuanghaoran.com.error.log;
}
```
uv × FastAPIの環境をDockerで構築

### 前提
- [uv](https://github.com/astral-sh/uv?tab=readme-ov-file#installation)がインストールされていること

<br />

### 本編
プロジェクト作成
``` shell
uv init uv-fastapi -p 3.12
```

<br />

fastapiをインストール
``` shell
cd uv-fastapi
uv add "fastapi[standard]"
```


<br />

hello.pyをmain.pyにリネームし、ファイルの中身を書き換える
``` py
from fastapi import FastAPI

app = FastAPI()


@app.get('/')
async def root():
    return {'message": "Hello World'}
```

<br />

Dockerfile作成
``` Dockerfile
FROM python:3.12-slim-bookworm

ARG DEVELOPMENT=0

# コンテナ内に.venvを作らないようにする環境変数
ENV UV_CACHE_DIR=/root/.cache/uv
ENV UV_LINK_MODE=copy
ENV UV_PROJECT_ENVIRONMENT='/usr/local/'
ENV UV_SYSTEM_PYTHON=1

WORKDIR /app

# NOTE: パッケージを追加したい場合はコメントアウトを解除し、`apt-get install`のパッケージを書き換えてください
#
# RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
#     --mount=type=cache,target=/var/lib/apt,sharing=locked \
#     apt-get update && \
#     apt-get install -y --no-install-recommends \
#         default-libmysqlclient-dev \
#         build-essential \
#         pkg-config

# バージョンを指定してuvをコピー
COPY --from=ghcr.io/astral-sh/uv:0.5.27 /uv /bin/uv

# Install dependencies
RUN --mount=type=cache,target=${UV_CACHE_DIR} \
    --mount=type=bind,source=uv.lock,target=uv.lock \
    --mount=type=bind,source=pyproject.toml,target=pyproject.toml \
    uv sync --frozen --no-install-project

ADD . /app

RUN --mount=type=cache,target=${UV_CACHE_DIR} \
    if [ $DEVELOPMENT = 1 ]; then \
        uv export --frozen --format requirements-txt > requirements.txt && \
        uv pip install -r requirements.txt; \
    else \
        uv export --frozen --no-dev --format requirements-txt > requirements.txt && \
        uv pip install -r requirements.txt; \

CMD ["uvicorn", "main:app", "--reload", "--host=0.0.0.0", "--port=8000"]

```

<br />

compose.yaml作成
```compose.yaml
services:
  api:
    build:
      context: .
      dockerfile: Dockerfile 
      args:
        DEVELOPMENT: 1
    volumes:
      - .:/app
      - /app/.venv # .vnevを空ディレクトリで上書きする(これがないとローカルの.venvの中身がコンテナの中に追加されちゃうんですよね、.dockerignoreも効果なし、知見求む)
    ports:
      - '8000:8000'
    tty: true

```

<br />

コンテナ起動
``` shell
docker compose up -d
```

<br />

ブラウザから http://localhost:8000/docs にアクセス
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/357470/b9a3915c-5178-45ce-a3a7-c3c8a60addc3.png)

<br />

以上


### uvの感想
これまではpyenvとvirtualenvで仮想環境を作ってpoetryでパッケージ管理してましたが、uvだけで全て完結できるようになったのでとても楽になりやした。

"uv"だけでググると紫外線が上位ヒットしちゃうのでもっとググラビリティが高い名前にしても良かったんじゃない?とは思う。

Rust製で高速を謳っているけども、パッケージマネージャの速度が問題になったことなんて無いから数秒単位の速度誤差は正直どうでも良いと思ったり思わなかったり。
Agile TPI についてまとめてみた

## はじめに
　先日参加した [DevelopersSummit2025](https://event.shoeisha.jp/devsumi/20250213) のセッションの中で聞いた Agile TPI に関して、私自身初めて聞いたフレームワークであり有用そうだと感じたので本記事では具体的な内容をまとめてみる。
(該当セッション：https://event.shoeisha.jp/devsumi/20250213/session/5527)

## Agile TPI （ Agile Test Practice Improvement ）とは
　テストプロセス改善のフレームワークのことであり、簡単に言うと、プロダクトの品質を向上させるためにテストプロセスの観点から改善していこうというものである。
　Agile TPI にはキーエリア、カテゴリ、チェックポイント、クラスタという4つの考えがあり、この考えを合わせてプロセス改善を行っていく。下でそれぞれの考えに関して説明していきたいと思う。

### キーエリア
　キーエリアとは、テストプロセスの評価軸や分類を指す。以下のように16つの観点に分類されており、この項目に関してそれぞれチェックを行っていき成熟度を計る（どのように成熟度を計るか、に関しては後述するチェックポイントを参照する）。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3526331/a92ef495-5a35-4890-86c6-2a7b4793aea6.png)

　さらに以下のようにキーエリア毎の優先度も定められているのでこの順に改善を実施していくことが推奨されている（優先度順に、緑>白>橙）。
 
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3526331/df1d16da-35c4-4685-b018-cc1b56758ba3.png)

### カテゴリ
　カテゴリとは、誰が、を分類したものである。以下のように個人レベル(P)、チームレベル(T)、組織レベル(O)の3つに分類される。上述したキーエリアに対して個人レベルではどうか、チームレベルではどうか、組織レベルではどうか、のように評価していき、Noと回答したセルに対してはYesとなるように施策を検討して改善を計っていく流れになる。
 ![スクリーンショット 2025-02-20 14.30.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3526331/dea7dab8-b5a3-4625-b177-3dec60ac7e26.png)

### チェックポイント
　チェックポイントとは、キーエリア毎にある複数の質問のことである。この質問にYes/No/回答不能と評価していく。以下のように、セル1つずつがそれぞれ質問となっているのでそれぞれに回答していきセルを埋めていく（Yes：緑、No：赤 のようにセルを塗っていくと視覚的に認知不可が下がる）。
![スクリーンショット 2025-02-20 14.47.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3526331/b4763f62-39c8-4e53-b715-12a9344cb3b3.png)

### クラスタ（優先度）
　クラスタとは各チェックポイント毎で優先度をつけたものである。優先度順にAからGまで定められている。
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3526331/0555bcbe-527a-49a5-9e53-5057940642b5.png)

　先ほどのキーエリアの優先順と合わせると以下のようになる。
![スクリーンショット 2025-02-20 15.10.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3526331/f0b21124-7186-475a-9513-8bef65b81ad7.png)

## 実施フロー
　以下で実際の全体的な簡単な流れを図とともに示す。
① チェックポイントの質問に回答する
② 取り組むチェックポイントを決定する
③ ポイントに対する施策を決定し実施する
④ 対象のポイントを振り返り、改善されていれば No → Yes とする
（② ~ ④ を繰り返す、大体1サイクルで1~2ポイントを対象としベイビーステップで改善していく）

```mermaid
graph TD;
    A[チェックポイントの質問に回答する] --> B[取り組むチェックポイントを決定する];
    B --> C[ポイントに対する施策を決定し実施する];
    C --> D[対象のポイントを振り返り、改善されたか確認];
    D -- 改善されていなければ --> C;
    D -- 改善されていれば --> B;
```

## 改善事例
 セッション内で聞いた改善事例を以下に記載する。
### 改善例①

<INS>取り組むチェックポイント</INS>
　プロダクトリスク分析、計画、準備、テストケース設計のようなテスト活動は、
テスト活動をスプリントのクリティカルパスとならないように、テスト実行よりも前に
行われている。

<INS>施策</INS>
　コーディング前にテスト設計、ケース作成を行うようにプロセスの変更。

### 改善例②

<INS>取り組むチェックポイント</INS>
　テストの役割を担う開発者が、特にテストエンジニアリングとテストケース設計に関するテストのトレーニングを受けている。

<INS>施策</INS>
　QAセミナーや輪読会の開催によって、テスト活動の知識やテスト技術を習得する。

## おわりに
　本記事ではデブサミ2025で気になった Agile TPI というフレームワークに関しての概要と、実践事例をまとめてみた。
 
## 参考
[ホワイトペーパーに関してはこちら](https://www.tmap.net/building-blocks/agile-test-process-improvement-agile-tpi)
[参考にしたセッション(実際に私が聞いたデブサミのものではないが)](https://www.youtube.com/watch?v=DT2UjOncYMg)
ThinkPad X13sにubuntuを入れる

普段仕事ではMacを使っているが、今回個人用だが新たにThinkPad X13sを手に入れたのでubuntuを入れて使ってみようと思い立ち着手したが思いのほか苦戦したので備忘録も兼ねて記事にしておく。

# 環境
- ThinkPad X13s
- Snapdragon8cx Gen3
- ubuntu24.10/windows11デュアルブート

# 用意するもの
- 4GB以上のUSBメモリ（今回は16GBのものを使用した）
- ubuntu24.10 iso イメージ
- Rufuns

# 手順
基本的には以下のサイトに記載の流れで行う。

https://launchpad.net/~ubuntu-concept/+archive/ubuntu/x13s

## ubuntu24.10のisoイメージをダウンロード
以下からダウンロードする。参考サイトに記載の最新の25.04では起動はできてもインストール時にマウントエラーが出てインストールできなかった。
実際このイメージ選定と下記のRufunsでめちゃくちゃハマった。
当初x13s用の専用イメージが用意されていたため、そちらを使ったら起動すらできずいろんなイメージをダウンロードしては試行錯誤した結果、最終的に以下のバージョンだけインストールできた。

https://cdimage.ubuntu.com/ubuntu/releases/24.10/release/

## Rufunsをダウンロード
以下からダウンロードする。筆者はイメージ作成をインテル製Windowsで行ったため、rufus-4.6.exeを使用した。

https://rufus.ie/ja/

![Screenshot 2025-02-20 153633.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137388/61011923-316b-4d4f-b572-d5d5bd1af2e0.png)


## RufunsでUSBメモリにisoイメージを焼く
ここでも大いにハマったが、イメージを焼くときはMBRではなくGPTを使い焼くこと。理由はよくわからないが、UEFIとの兼ね合いなのかGPTにしなければインストール実行時にエラーとなった。

![Screenshot 2025-02-20 154048.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137388/2e58c0b4-6870-45f3-94e1-d1b249be4614.png)

## windowsのディスク管理でパーティションを縮小
Windowsマークを右クリックして、ディスク管理を選択、縮小したいドライブを選択してボリュームを縮小する。
この時、特に再割り当てなどせず縮小したままにしておくのがよい。

https://support.microsoft.com/ja-jp/windows/%E3%83%87%E3%82%A3%E3%82%B9%E3%82%AF%E3%81%AE%E7%AE%A1%E7%90%86%E3%81%AE%E3%83%98%E3%83%AB%E3%83%97-ad88ba19-f0d3-0809-7889-830f63e94405

https://learn.microsoft.com/ja-jp/windows-server/storage/disk-management/shrink-a-basic-volume

## Bitlockerを解除
Bitlockerが有効になっている場合、このタイミングで先に行っておいたほうがよいと思われる。
GUIでできるようだが筆者はコマンドにて行った。

https://learn.microsoft.com/ja-jp/windows-server/administration/windows-commands/manage-bde-off

https://www.ubackup.com/jp/windows-11/windows-11-disable-bitlocker-encryption.html

## PC再起動してBIOSを起動しセキュアブートをオフにする
一度PCをシャットダウンして再度起動、Lenovoの文字が出てるところでF12を押してBIOSを起動する。
その中のApp Menu > SetUp > Securty > Secure Bootの項目をOFFにする。
それプラスSetUp > Config > Linux > Linux Boot (Beta)という項目を有効にする必要があった。

## 再度Windowsを起動してBitlockerの回復キーを入力
この状態でWindowsを起動するとBitlockerの回復キーを入力する画面が表示される場合は回復キーを入力する。（調べた感じHomeや、ProでもBitlockerを最初から使ってないとでないっぽい？）
回復キーをメモしてなかったらマイクロソフトアカウントに紐づけていれば以下から取得できる。
回復キーを入力して問題なければWindowsが立ち上がる。

https://support.microsoft.com/ja-jp/windows/bitlocker-%E5%9B%9E%E5%BE%A9%E3%82%AD%E3%83%BC%E3%82%92%E8%A6%8B%E3%81%A4%E3%81%91%E3%82%8B-6b71ad27-0b89-ea08-f143-056f5ab347d6

https://aka.ms/myrecoverykey

## PCの電源を落とし、ubuntuが入ったUSBメモリを指して起動
Lenovoの画面でF12を押してUSBメモリからBootする。

## ubuntuをインストールする
無事Ubuntuが起動できたらインストールを実行する。

# 大変だったこと
以下のデイリービルドや専用イメージではどう頑張っても筆者の環境ではインストールができなかった。
https://cdimage.ubuntu.com/ubuntu/daily-live/current/
専用イメージなのにそもそも起動すらしないし、25.04だと起動こそできたがインストールしようとすると何故かUSBマウントエラーが出てインストール画面にいけない。
ArchLinuxも同様にダウンロードして試したけどそちらもうまくいかず。
結局試行錯誤して24.10のイメージ+Rufns(GPT選択)で行くことができた。
これに気付くまでめちゃくちゃ時間を使ってしまった。

スナドラ搭載ThinkPadっていうニッチなデバイスだけど、同じような人がいたら少しでも参考になれば。

では良きUbuntuライフを！
iOSでMVVMをやってる時に、カオスになったRxSwfitのバインディング処理をスッキリしたかった【骨組み編】

~~~~~~~~~~~~~~~~~~~~~~~
4年半ぶりに復帰！
生成AIやら、SwiftUIやら、
世界が変わってししまいましたが、
なんとかiOSエンジニアとして生き残っています。
~~~~~~~~~~~~~~~~~~~~~~~

iOS開発でMVVMをやってる時に、
* ViewControllerやViewModel内の<B>バインディング</b>がぐちゃぐちゃになった
* どのプロパティがどこにバインドされてるかわからん
* Outputのはずなのに、他のOutputにInputとしてそのまま使われてる

など、バインド処理がぐちゃぐちゃで鬱になったので、役割ごとに切り分けることで、すっきりさせる設計を色々試しました。

# で、どのように分けたか

* Input
    * Viewからの入力
        * ボタンのタップ
        * テキストの入力
        * ライフサイクル
* Output
    * ViewModelからViewへ通知
        * テキストの更新
        * 色の更新
        * 画像の更新
* Navigation
    * ViewModelからControllerへ通知
        * 次の画面へ進むトリガー
        * 前の画面へ進むトリガー
        * エラーダイアログ表示トリガー

# 骨組み
全コードを記載すると、全体が見渡しにくいので、骨組みだけ記載します。

## ViewModel

```swift

/// ViewModel
final class SampleViewModel {
    /// 入力
    struct Input {
        // 画面から受け取る入力を定義
    }
    
    /// 出力
    struct Output {
        // 画面へ出力する内容を定義
    }
    
    /// 画面遷移
    struct Navigation {
        // 画面遷移を定義
    }
    
    init() {}

    /// Inputをバインディング
    func bindViewModel(input: Input) -> (Output, Navigation) {
        // inputとModelを利用して、OutputとNavigationを紐づける
        let output = Output()
        let navigation = Navigation()
        return (output, navigation)
    }
}

```

## ViewController

```swift
/// ViewController
final class SampleViewController<ViewModel: SampleViewModel>: UIViewController {

    /// ViewModel
    private let viewModel: ViewModel
    /// Input
    private var input = ViewModel.Input

    init(_ viewModel: ViewModel) {
        self.viewModel = viewModel
        self.input = .init()
        super.init(nibName: nil, bundle: nil)
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        bindViewModel()
    }
    
    /// ViewModelとバインド
    private func bindViewModel() {
        bindIntput(input)
        let (output, navigation) = viewModel.bind(input)
        bindOutput(output)
        bindNavigaion(navigation)
    }
    
    /// 画面の操作をバインド
    private func bindInput(_ input: ViewModel.Input) {
    }
    
    /// ViewModelの出力をバインド
    private func bindOutput(_ output: ViewModel.Output) {
    }
    
    /// 画面遷移をバインド
    private func bindNavigation(_ navigation: ViewModel.Navigation) {
    }
}
```

# 今後
* 実際の実装レベルのサンプルを公開
    * UseCaseとRepositryも含める

* 画面の中に画面がある、カスタムViewの入れ子状態の時、View間でやりとりするとぐちゃぐちゃになるので、Model層で効率的に連携する方法を模索
* 生成AIでサクッと機能を追加するテンプレ呪文を考えたい

# 参考
https://github.com/tailec/ios-architecture
ファイル階層から次の階層を見つける

```
' Module to extract next level files/folders under specified path
Option Explicit

' ･皈､･Iﾀ・
Sub GetNextLevelItems()
    Dim ws As Worksheet
    Dim lastRow As Long
    Dim i As Long
    Dim rootPath As String
    Dim searchPath As String
    Dim pathParts() As String
    Dim targetLevel As Long
    Dim dict As Object
    Dim resultStr As String
    
    ' Get input path (e.g. "/boot/efi")
    rootPath = InputBox("Enter root path to search", "Path Input", "/boot/efi")
    If rootPath = "" Then Exit Sub
    
    ' Convert path to space-delimited format (e.g. "boot efi")
    searchPath = Replace(Trim(rootPath), "/", " ")
    searchPath = Trim(searchPath)
    pathParts = Split(searchPath, " ")
    targetLevel = UBound(pathParts) + 1
    
    Set dict = CreateObject("Scripting.Dictionary")
    
    ' Get data range
    Set ws = ThisWorkbook.Sheets("Sheet1")
    lastRow = ws.Cells(Rows.count, 1).End(xlUp).Row
    
    
    ' Process data rows
        For i = 1 To lastRow
        Dim currentPath As String
        Dim currentParts() As String
        
        currentPath = ws.Cells(i, 1).Value
        For k = 2 To 10
            If ws.Cells(i, k).Value = "" Then
             Exit For
            End If
            currentPath = currentPath & " " & ws.Cells(i, k).Value
        Next k
        
        currentPath = Replace(Trim(currentPath), "  ", " ")
        currentParts = Split(currentPath, " ")
        
        ' Process only when hierarchy level matches search path +1
        If UBound(currentParts) = targetLevel Then
            Dim matchFlag As Boolean
            Dim j As Long
            
            matchFlag = True
            For j = 0 To targetLevel - 1
                If currentParts(j) <> pathParts(j) Then
                    matchFlag = False
                    Exit For
                End If
            Next j
            
            If matchFlag Then
                ' Add item avoiding duplicates
                'If Not dict.exists(currentParts(targetLevel)) Then
                If Not ws.Cells(i, targetLevel + 1) = "" Then
                    dict.Add currentParts(targetLevel), ""
                End If
                
                
                
            End If
        End If
    Next i
    
    ' Convert results to string
    resultStr = Join(dict.keys, vbCrLf)
    
    ' ｽYｹ訷ｦ
    If dict.count > 0 Then
        MsgBox resultStr, vbInformation, "Search Results"
    Else
        MsgBox "No matching items found", vbExclamation
    End If
End Sub



```vb
FPGAでレート変換を実装するときの効率的な実装テクニック

## 目的
最近、リサンプリング（レート変換）をFPGAに効率的に実装するテクニックを知ったので、備忘録がてらまとめておきます。
この記事は実装上の嬉しさにのみ言及しており、原理については記載しておりません。そちらについては専門書をご覧ください。

## 背景
ワイヤレスや、音声信号処理のアプリケーションにおいて、レート変換をしたい、というときが有るかと思います。例えば、ワイヤレスのアプリケーションにおいて、ADコンバータではサンプリング周波数が10GSPSであっても、実際に変調されたベースバンド信号のレートが低い場合、レートを下げて処理することでリソース消費量を減らしたい、といったことが有るかと思います。この時、単純に間引きをしてしまうとエイリアシングが発生してしまうので、事前にフィルタを使って高い周波数成分を取り除き、そのあと間引きを行います。

こちらの記事が分かりやすいです。
https://edn.itmedia.co.jp/edn/articles/1208/10/news093.html

このような「フィルタ」＋「間引き」が一体になった処理をデシメーションといいます。
さて、このような処理を実装するにあたって、高いレート変換比が必要であるとき、フィルタのタップ数が多くなってしまい、多くのリソースを消費してしまいます。

## ソリューション
このような場合、フィルタを多段に分割することで、リソース消費量を大きく減らすことが出来ます。
例えば、サンプリングのレートを1/50にする場合を考えます。
この時、１ステージで1/50とするよりも、1/5⇒1/5⇒1/2とすることで、リソース消費量を減らすことが出来ます。
Simulinkにて、Decimationというブロックがあるので、こちらを使って単純比較してみました。

- 作ったモデルとリソース消費量の比較
![スクリーンショット 2025-02-20 152410.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569326/fdc5f23a-efdf-436e-a1ed-8298cdc86ebe.png)

- 単段のデシメーションフィルタ
![スクリーンショット 2025-02-20 152057.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569326/fd74b00d-4822-437d-aad6-5fb4e2c40888.png)

- 単段のデシメーションフィルタの結果
![スクリーンショット 2025-02-20 152758.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569326/6d7a3d63-69c5-48b9-ae14-6879476050cd.png)

- 多段のデシメーションフィルタ
![スクリーンショット 2025-02-20 152105.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569326/b00c5627-6939-42fc-b99b-46c7493685d9.png)

- 多段のデシメーションフィルタの結果
![スクリーンショット 2025-02-20 152835.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569326/ae55a4ba-441b-44c7-8c50-aa0fbc978121.png)

結果を見ると、なにも考えず縦に分割して繋いだだけでも、同じような特性が出ていることが分かります。

合成した結果を抜き出すと、下記の通りとなりました。
| Resource | Usage(1stage) | Usage(Multistage) |
|---|---|---|
|CLB LUTs|3556|4212|
|CLB Registers|5866|4873|
|DSPs|288|80|
|Block RAM Tile|0|0|
|URAM|0|0|

結果を見ると、特にDSPの消費量を大きく抑えられていることが分かりました。
一方、LUTの消費量は増大しているようです。DSPの代わりにロジックブロックが割り当たっているのかもしれません。
【Flutter】プラットフォームごとに挙動が異なる場合のウィジェットテスト

[プラットフォーム（OS）によって遷移先の画面を変える](https://qiita.com/k-yamauchi_/items/b98dfbd47249f2c48108)機能のウィジェットテストを書いていた際
日本語の情報が見つからずちょっとした躓きポイントにハマってしまったのでその対処の記録です。

プラットフォームにより異なる挙動を一つの環境でテストするには、テスト実行時プラットフォームを偽装する必要があります。
またそれだけでなく、プロダクトコード側のプラットフォーム判別もテスト時の偽装に対応したものでなければならない：
具体的には `dart:io` の `Platform.isXxx` は偽装に適応する仕組みがないため使えず、`flutter/foundation` の `defaultTargetPlatform` でないといけないのですが
その辺りまではテスト時の具体的な偽装のやり方共々 下記記事に一通り書かれているのでそちらをご覧下さい。

https://qiita.com/Harx02663971/items/5bccf49b012756f36adb

`debugDefaultTargetPlatformOverride` に `TargetPlatform.xxx` をセットしてプラットフォーム偽装を行った際は
上記記事内にもあるようにそのテストから抜ける際に必ず `debugDefaultTargetPlatformOverride` に `null` を(再)セットする必要があり、忘れると下記のようなエラーでテストが失敗します。

```
══╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ╞════════════════════════════════════════════════════
The following assertion was thrown running a test:
The value of a foundation debug variable was changed by the test.

When the exception was thrown, this was the stack:
#0      debugAssertAllFoundationVarsUnset.<anonymous closure> (package:flutter/src/foundation/debug.dart:41:7)
#1      debugAssertAllFoundationVarsUnset (package:flutter/src/foundation/debug.dart:44:4)
#2      TestWidgetsFlutterBinding._verifyInvariants (package:flutter_test/src/binding.dart:1068:12)
#3      AutomatedTestWidgetsFlutterBinding._verifyInvariants (package:flutter_test/src/binding.dart:1525:11)  
#4      TestWidgetsFlutterBinding._runTestBody (package:flutter_test/src/binding.dart:1049:7)
<asynchronous suspension>
<asynchronous suspension>
(elided one frame from package:stack_trace)

The test description was:
  Your Test Case Name
════════════════════════════════════════════════════════════════════════════════════════════════════
```

ならば `tearDown()` でnullをセットすればいいよね、上記の記事にもそう書かれているしということで

```dart
tearDown(() {
  debugDefaultTargetPlatformOverride = null;
});
```

これでOKっしょ・・・と思ったのですがテスト結果変わりません。エラー内容も同じ。
えぇ？ なんでナンデ??　と情報探し回ったりコード弄りまわしてみたりすることしばし、見つかった英語の情報から得た結論は
**ウィジェットテストの場合 `tearDown()` でnullセットしてはならず、各テストの末尾にnullセット処理を都度書かないといけない** でした。

https://stackoverflow.com/questions/57628195/how-to-stub-target-platform-in-flutter

回答末尾の **Important:** 以下をざっくり訳すと

> `debugDefaultTargetPlatformOverride = null` を `tearDown()` に移したくなるだろうけどそれだと動かない
> 何故なら `debugAssertAllFoundationVarsUnset()` は `tearDown()` より前に呼ばれるから

という感じでしょうか（若干意訳）。直前の節で

> debugDefaultTargetPlatformOverride はテスト全体に影響するトップレベル変数なので各テスト終了時には null にリセットされていなければならないので `debugAssertAllFoundationVarsUnset()` でそのチェックを行う

とも書かれている（同）ので、ウィジェットテストでは `tearDown()` より前に `expect(debugDefaultTargetPlatformOverride, isNull)` みたいな検証がされるんだな～と理解しておけばよさそうに思いました。
bedrock claude 3.5 sonnet v1 : アップロード可能ファイル拡張子

# 前置き
- bedrock claude 3.5 sonnet v1 の対応するファイル拡張子を見つける
    - 簡単に検索しただけでは分からなかった
- AI を少し用いる




# 結果
- playground の chat interface 
    - gif
    - webp
    - jpeg
    - png
- [converse api](https://community.aws/content/2i4v2vZRb9YgL2RxkawPiF8f0lZ/using-document-chat-with-the-amazon-bedrock-converse-api) を使用した場合
    - gif
    - jpeg
    - png
    - webp
    - docx
    - csv
    - html
    - txt
    - pdf
    - md
    - doc
    - xlsx
    - xls
- file size 上限
    - ドキュメント : 4.5MB   # pdf で試行
    - 画像 : 25MB   # png で試行



# 案
playground chat では uploadable ファイルのみ添付可能.
様々な拡張子でファイルを作成し, 当該 chat interface 上で uploadable 拡張子を見つける.


 
 
 
# ファイル作成 AI に任せる
漸進的に進めファイルを作成する

- 1 : ビジネス, IT開発において一般的に使用される拡張子を列挙
- 2 : [ 1 ] の結果に不足があれば拡張子の追加を指示する
- 3 : [ 2 ] の拡張子群を元に, ダミーファイルを作成する touch command の作成指示を行う
- 4 : [ 3 ] を手動で実行しファイルを作成
- 5 : playground で読み込み可否を確認する




# 生成された commands
```bash
touch document.doc document.docx
touch spreadsheet.xls spreadsheet.xlsx
touch presentation.ppt presentation.pptx
touch report.pdf
touch notes.txt
touch readme.md
touch data.csv

touch script.py script.rb
touch script.js script.ts
touch program.java
touch code.c code.cpp code.cs
touch main.go main.rs
touch script.php
touch script.sh
touch script.bat

touch index.html
touch style.css
touch style.scss style.sass
touch config.json
touch data.xml
touch settings.yml settings.yaml

touch query.sql
touch database.db
touch storage.sqlite
touch access.mdb access.accdb

touch archive.zip archive.tar
touch compressed.gz
touch backup.7z
touch package.rar

touch app.exe
touch library.dll
touch module.so
touch binary.bin
touch disk.iso

touch vm.ova
touch disk.vmdk
touch disk.vdi
touch Dockerfile

touch .gitignore
touch .gitattributes
touch .editorconfig
touch .env

touch image.jpg image.jpeg
touch image.png
touch animation.gif
touch vector.svg
touch design.psd
touch illustration.ai
touch picture.bmp
touch photo.tiff photo.tif
touch graphic.webp
touch capture.heic
touch raw_image.raw
touch camera.cr2
touch camera.raf
touch camera.nef
touch camera.orf
touch camera.sr2
touch camera.dng

touch video.mp4
touch movie.avi
touch clip.mov
touch audio.mp3
touch sound.wav
```




# chat からファイル選択ダイアログを表示
受付可能ファイルのみが白文字となる
![スクリーンショット 2025-02-20 15.49.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118627/62a3e714-c08b-411a-a799-749ae91c755d.png)




# 所感
- 数分で作成できたので楽でした
- ハルシネーション
    - 存在しない拡張子も含まれるかもしれないが, この場合では問題無い
- claude 3.5 sonnet v1 が playground で受け付けている拡張子は意外と少ない




# 補足
こちらがより正確
[converse api](https://community.aws/content/2i4v2vZRb9YgL2RxkawPiF8f0lZ/using-document-chat-with-the-amazon-bedrock-converse-api) call 時に適当な拡張子を指定すると, 応答として返してくれました.
また, converse api では claude 3.5 sonnet v1 でもドキュメント系のファイルが受付可能でした 


```
Member must satisfy enum value set: 
[docx, csv, html, txt, pdf, md, doc, xlsx, xls]
```

```
 Member must satisfy enum value set: 
 [gif, jpeg, png, webp]
 ```

# 補足2
bedrock claude 3.5 sonnet `v2` では playground chat からドキュメントタイプのファイルも読み込み可能でした
The file does not exist at "/node_modules/.vite/deps/chunk-YWORYFCF.js?v=120e3784" which is in the optimize deps directory. の対処法

`The file does not exist at "/node_modules/.vite/deps/chunk-YWORYFCF.js?v=120e3784" which is in the optimize deps directory. The dependency might be incompatible with the dep optimizer. Try adding it to `optimizeDeps.exclude`.`のエラーに関する対処法。
開発環境で以上の様なエラーに遭遇した。jsxファイルをカテゴリごとにフォルダにまとめる作業をしていたら遭遇した。

対処法:キャッシュをクリアする

これで治ったので、同じ様なエラーに遭遇した人は試してみるとよい。

参考

https://github.com/vitejs/vite/discussions/17738
Todoist APIを使って、Todoist CLIクライアントを作ってみた。

## Todoist APIを使って、Todoist CLIクライアントを作ってみた。

### はじめに

Todoistは人気のタスク管理ツールですが、普段ターミナルを多用する開発者にとっては、CLIからタスクを管理できると便利です。そこで、Todoist APIを活用して、シンプルなCLIクライアントを作成しました。本記事では、その概要と使い方を紹介します。

### Todoistとは？
毎日のやるべきことをオンライン上で管理できるタスクツールです。ブラウザとスマホアプリケーションどちらも対応しているため、外ではIphoneで開いて、家ではパソコンで開いてなんて使い方もできます。
⇒ [Todoist公式](https://www.todoist.com/ja)

### 僕の普段の使い方
普段はTodoistをメモ、後でやること、タスクがごちゃごちゃになったとき書き込むという使い方をしています。毎日使う分には、様々な機能は使わないというのが正直なところです。

### 欲しかったもの
パソコン作業中にわざわざTodoistのブラウザを開いたりするのはめんどうです。また、普段はコマンドラインで作業をしていることが多くマウスに持ち替えるのもめんどうです。
なので、コマンドライン上でTodoistを扱えたら最高じゃん！ってことになりました。

### 既存のものではだめなの？
Github上にはいくつかのTodoist CLIクライアントが存在します。
しかし、様々な機能がついていたので、とにかくシンプルなものを作りたかったです。

---

### リポジトリ情報

今回作成したCLIツールのソースコードは、GitHubで公開しています。

🔗 [リポジトリ: todoist-CLI](https://github.com/kentyja12/todoist-CLI)

このツールを使用することで、ターミナル上でTodoistのタスクを追加、一覧表示、完了することができます。

---

### 機能概要

このCLIツールでは、以下の操作を行うことができます。

- **タスクの追加** (`todo add`)
- **タスクの一覧取得** (`todo ls`)
- **タスクの完了** (`todo check`)

すべての操作は、Todoist APIを通じて行われます。

---

### 環境構築

1. **Python のインストール**
   
   本ツールは Python で作成されているため、Python 3.7 以上が必要です。
   
2. **リポジトリのクローン**
   
   ```sh
   git clone https://github.com/kentyja12/todoist-CLI.git
   cd todoist-CLI
   ```
   
3. **必要なパッケージのインストール**
   
   ```sh
   pip install -r requirements.txt
   ```
   
4. **環境変数の設定**
   
   `.env` ファイルを作成し、以下の情報を記載します。
   
   ```
   TODOIST_TOKEN=your_todoist_api_token
   INBOX_ID=your_todoist_inbox_project_id
   ```
   
   `TODOIST_TOKEN` は [Todoist API](https://developer.todoist.com/guides/#developing-with-todoist) から取得できます。

---

### 使い方

#### タスクを追加

タスクを追加するには、以下のコマンドを実行します。僕は基本的にこのコマンドしか使ってません。

```sh
todo add "新しいタスク"
```

また、特定のプロジェクトに追加したい場合は `-p` オプションを指定します。

```sh
todo add "プロジェクト用タスク" -p 123456789
```

---

#### タスクの一覧表示

現在のタスクを表示するには、以下のコマンドを実行します。またまた僕はこのコマンドしかつかってｍ

```sh
todo ls
```

特定のプロジェクトのタスクを表示したい場合は `-p` オプションを使用します。

```sh
todo ls -p 123456789
```

---

#### タスクの完了

タスクを完了するには、タスクの番号またはタスク名を指定します。

```sh
todo check 1
```

または、複数のタスクを一度に完了することも可能です。

```sh
todo check 1 2 "特定のタスク名"
```

---

### 実装のポイント

このツールの主なポイントは以下のとおりです。

1. **Todoist APIを活用**
   - `todoist_api_python` ライブラリを利用して、API経由でタスクを操作

2. **タスクをプロジェクトのセクションごとに管理**
   - タスクを最初のセクションに追加する仕組みを実装

3. **リポジトリの自動更新**
   - 一日の最初の実行時に `git pull` でリポジトリを更新

4. **エラーハンドリングの実装**
   - API通信やリポジトリ操作で発生するエラーを適切に処理

---

### まとめ

本記事では、Todoist APIを活用して作成したCLIツールについて紹介しました。このツールを使えば、ターミナルから簡単にTodoistを操作できるため、タスク管理がより効率的になります。

興味のある方は、ぜひ [GitHubのリポジトリ](https://github.com/kentyja12/todoist-CLI) をチェックしてみてください！

今後も機能追加を行っていく予定なので、コントリビューションも歓迎です！

### 参考
- Todoist 公式サイト: https://www.todoist.com/ja
- Todoist Developing with Todoist: https://developer.todoist.com/guides/#developing-with-todoist