OmniAICreator/Qiita-1.07M huggingface dataset:
C++で例外をcatchしないとどうなるか？実行時エラーとその対処法

## ✅発生したエラーとその意味

```bash
terminate called after throwing an instance of 'std::invalid_argument'
  what():  0より大きい数値を入力してください。
run: line 1:     3 Aborted                 (core dumped) LD_LIBRARY_PATH=/usr/local/gcc-9.2.0/lib64 ./a.out
```

- `terminate called after throwing an instance of 'std::invalid_argument'`

→ `std::invalid_argument` 型の例外が投げられた（throwされた）あとに、`terminate()` が呼ばれて**異常終了**したことを示している。

- `what(): 0より大きい数値を入力してください。`
    
    → `throw` 時に渡したメッセージ（`what()` の中身）が表示されている。
    
    つまり、例外オブジェクトが**なぜエラーなのか**を伝えてくれている部分。
    
- `Aborted (core dumped)`
    
    → 例外が捕まえられなかった（catchされなかった）ため、**プログラムがクラッシュ（Abort）して、メモリダンプが出力された**ことを示している。
    

## ⚠️ 原因

以下のコード内で`throw`によって例外（`std::invalid_argument`）が投げられているが、`main()`関数内で`try-catch`による処理がされていなかったため、プログラムが例外未処理のまま異常終了した。

```cpp
if (val <= 0) {
    throw std::invalid_argument("0より大きい数値を入力してください。");
}
```

## 🛠 解決策

- 大前提：例外を投げたら必ずどこかで受け取って処理すること。
- 例外が発生する可能性のある関数を呼び出す時は、`try-catch`文で囲んで例外を適切に処理すること。
- これにより、プログラムのクラッシュが防ぎ、ユーザーに適切なエラーメッセージを提示できる。
- また、`what()`を使えば、例外の詳細なメッセージを取得可能。

## ✅修正後のコード例

```cpp
#include <iostream>
#include <string>
#include <stdexcept>

std::string convertVal (int val, std::string type) {
    std::string result;
    int divisor;

    // 例外処理
    if (val <= 0) {
        throw std::invalid_argument("0より大きい数値を入力してください。");
    }

    // 16進数に変換する場合
    if (type == "hex") {
        divisor = 16;
    // 2進数に変換する場合
    } else if (type == "bits") {
        divisor = 2;
    }   

    // 以下で余りを16進数や2進数に変換していく
    while (val > 0) {
        int remaind = val % divisor;

        if (type == "hex" && remaind >= 10) {
            int diff = remaind - 10;
            char hex = 'A';
            hex += diff;
            result = hex + result;
        } else {
            result = std::to_string(remaind) + result;
        }

        val /= divisor;
    }

    return result;
}

int main () {

    try {
        std::cout << convertVal(0, "bits") << std::endl;
    } catch (const std::invalid_argument& e) {
        std::cerr << "入力エラー" << e.what() << std::endl;
        return 1;
    }

    return 0;
}
```

## 💡補足

- `catch`では`const std::invalid_argument& e`のように「const参照」で受け取ることで、無駄なコピーを避けつつ安全に例外メッセージを参照できる。
- そもそもエラーとは、プログラムが正常に動かない状況全般のこと。その中で、意図的に throw できて、try-catch で対応できるものを「例外」と呼ぶ。
- Pythonのようなインタプリタ言語は、例外を自動で発生させてくれる場面が多いが、C++のようなコンパイル言語では、開発者が自分で throw して例外処理を書く必要がある。
- 例外処理の目的は、プログラムのクラッシュを未然に防いだり、安全に終了したり、代替処理を入れたりするため。
Node.jsプロジェクト開始方法

# JSプロジェクト開始方法

1. Node.jsインストール

1. プロジェクトコマンド作成

```jsx
mkdir my-project  //フォルダ作成

cd my-project     //フォルダに移動
```

1. npm初期化　（package.json作成）

```jsx
npm init -y
```

1. 必要なモジュールのインストール

```jsx
npm install express
```

5．コーディング　server.jsファイルなどを作成しコーディング

```jsx
const express = require('express');
const app = express();

app.get('/', (req, res) => {
  res.send('Hello World');
});

app.listen(3000, () => {
  console.log('Server is running on http://localhost:3000');
});

```

6.　サーバー起動

```jsx
node index.js
```

1. ブラウザでアクセス

```jsx
http://localhost:3000
```
AIがwebで使えるツール集を作った[Next.js]

## はじめに

Copilotを積極的に活用し、通常よりも短期間で「PocketALL」というWebアプリを完成させることができました。的確なコード提案のおかげで、初心者ながらも複雑な実装にチャレンジでき、学習と開発を同時に進めることができました。このアプリは、日常的によく使う便利ツールを一箇所にまとめ、ブラウザ上で手軽に利用できるよう設計しています。

https://pocket-all.vercel.app


## 実装した機能

現在、PocketALLには以下の4つの機能を実装しています：

### 1. QRコード生成

URLやテキストを入力するだけで、すぐにQRコードが生成できる機能です。生成したQRコードは画像としてダウンロードも可能です。

実装には `qrcode.react` ライブラリを使用し、入力内容に応じてリアルタイムでQRコードが更新される仕組みにしました。

### 2. 画像透過

アップロードした画像の背景を自動的に透過させる機能です。特に商品画像やアイコン作成時に便利です。

この機能は `@imgly/background-removal` ライブラリを活用し、AIを使って画像から背景を自動検出・除去します。ユーザーインターフェースには以下の要素を実装しています：

- ドラッグ&ドロップによる画像アップロード
- 処理中のリアルタイム進捗表示
- Web Share API対応（モバイル端末での共有に最適）

ブラウザ上で完結する設計のため、ユーザーの画像はサーバーに送信されることなく、プライバシーを保ちながら高品質な透過処理を実現しています。

### 3. 画像圧縮

高解像度の画像をWebに適した形式・サイズに圧縮する機能です。アップロードした画像を、品質を保ちながらファイルサイズを削減します。

`browser-image-compression` ライブラリを活用し、圧縮率と品質のバランスを調整できるUIを設けました。以下のような特徴があります：

- **スライダーによる圧縮品質調整**: 1%〜100%の範囲で画質とファイルサイズのバランスを簡単に調整
- **出力解像度の選択**: 400pxの小サイズから8K(7680px)まで、用途に合わせた解像度を選択可能
- **複数の出力形式**: JPEG、PNG、WebPの3形式から選択可能
- **圧縮効果の可視化**: 元のサイズ、圧縮後サイズ、削減率をリアルタイム表示
- **ドラッグ＆ドロップ対応**: ブラウザへの簡単なファイルアップロード
- **レスポンシブUI**: モバイル端末でも使いやすいインターフェース


モバイル端末では、Web Share APIを利用して圧縮した画像を他のアプリに直接共有できる機能も実装しました。PCブラウザでは通常のダウンロード機能が使用されます。

### 4. 単位変換

長さ、重さ、温度など様々な単位を相互に変換できる機能です。日常のちょっとした計算に便利です。

この機能は自作の変換ロジックを使い、React Hooksを活用して状態管理を行っています。以下のような特徴があります：

- **複数のカテゴリー対応**: 長さ、重さ、温度、面積、体積など様々な単位系に対応
- **直感的なインターフェース**: 変換元と変換先の単位をドロップダウンで簡単に選択
- **リアルタイム変換**: 入力値が変わると即座に変換結果が表示される
- **単位の入れ替え機能**: ボタン一つで変換元と変換先を入れ替え可能
- **よく使われる変換**: カテゴリーごとによく使われる変換パターンをワンクリックで適用

変換ロジックは基準単位（SI単位系など）を介して計算することで、あらゆる単位間の正確な変換を実現しています。例えば、長さであればメートル、重さであればキログラムを基準単位として、各単位からの変換関数を定義しています。

アプリケーション内で独自のデータ構造を設計し、各単位カテゴリーに以下の情報を持たせています：

```typescript
{
  id: "length",
  name: "長さ",
  units: [
    {
      id: "m",
      name: "メートル (m)",
      toBase: (value) => value,         // 基準単位への変換関数
      fromBase: (value) => value        // 基準単位からの変換関数
    },
    {
      id: "km",
      name: "キロメートル (km)",
      toBase: (value) => value * 1000,
      fromBase: (value) => value / 1000
    },
    // 他の単位...
  ],
  commonConversions: [["m", "ft"], ["km", "mile"]] // よく使われる変換
}
```

## 技術スタック

PocketALLは以下の技術を使って構築しています：

- **フロントエンド**: Next.js (React)
- **言語**: TypeScript
- **スタイリング**: Tailwind CSS + daisyUI
- **デプロイ**: Vercel

## 開発で学んだこと

GitHub Copilotを活用することで、開発時間を大幅に短縮できましたが、同時にAIとの協業の仕方も学びました。特に、明確な指示をコメントとして書くことで、より適切なコード提案が得られることがわかりました。また、Copilotが生成したコードを理解し、必要に応じて修正する過程で、技術的な理解も深まりました。

## 今後の展望

まだまだ改善の余地はありますが、少しずつ機能を拡張していきたいと思います。

## おわりに

この記事も、Github Copilotが8割程生成してくれました。

制作したPocketALLは、下記のURLからアクセスできます。ぜひお試しください。

URL: [PocketALL](https://pocket-all.vercel.app)

https://pocket-all.vercel.app


## ソースコード

GitHubでソースコードを公開しています。
[GitHub: PocketALL](https://github.com/yuto0623/pocket-all)

https://github.com/yuto0623/pocket-all
ソフトウェアテスト

## 目次

1. [はじめに](#はじめに)
2. [テストの種類](#テストの種類)
   - [単体テスト（Unit Test）](#単体テストunit-test)
   - [結合テスト（Integration Test）](#結合テストintegration-test)
   - [システムテスト（System Test）](#システムテストsystem-test)
   - [エンドツーエンドテスト（E2E Test）](#エンドツーエンドテストe2e-test)
3. [まとめ](#まとめ)

## はじめに

ソフトウェア開発において、テストは品質を保証し、バグを未然に防ぐための重要なプロセスです。本記事では、テストの種類、目的、実施方法について詳しく解説します。

## テストの種類

### 単体テスト（Unit Test）

**概要**  
- 最小の単位（関数、メソッド、クラス）でのテストを行う。
- 外部の依存関係をモック化し、対象のコード単体で動作を確認する。

**目的**  
- 個々のコンポーネントが正しく動作することを確認する。
- バグを早期に発見し、修正することができる。

**使用ツール（例）**  
- Python: `pytest`, `unittest`
- JavaScript: `Jest`, `Mocha`
- Java: `JUnit`

### 結合テスト（Integration Test）

**概要**  
- 複数のモジュールやコンポーネントを組み合わせた際の動作を確認する。
- APIやデータベースとのやり取りも含める。

**目的**  
- コンポーネント間のインターフェースが正しく連携するかを検証する。
- 外部サービスとの接続が意図したとおりに動作するかを確認する。

**使用ツール（例）**  
- Python: `pytest-django`, `Django Test Client`
- JavaScript: `Jest`, `Supertest`
- Java: `TestNG`

### システムテスト（System Test）

**概要**  
- アプリケーション全体の動作を確認するテスト。
- UI、API、データベース、ネットワークなどを含む包括的なテストを行う。

**目的**  
- システム全体が要件どおりに動作するかを確認する。

**使用ツール（例）**  
- Selenium（Webアプリ）
- Cypress（Webアプリ）
- Postman（APIテスト）

### エンドツーエンドテスト（E2E Test）

**概要**  
- 実際のユーザー操作に近い形でアプリケーションをテストする。
- UIの操作からバックエンドとのやり取りまで含めたシナリオテストを行う。


**システムテストとの違い**

システムテストが主に仕様通りの動作を確認するのに対し、E2Eテストはユーザーの操作シナリオに基づいてシステム全体の機能性を検証する点が異なる

**目的**  
- ユーザーフロー全体が問題なく動作することを保証する。

**使用ツール（例）**  
- Selenium（Webアプリ）
- Cypress（Webアプリ）
- Appium（モバイルアプリ）


## まとめ

ソフトウェアテストは、テストは品質を保証し、バグを未然に防ぐための重要なものであるので、各テストの目的や特徴を理解し、目的に合ったテストを実行していきたい。
情報処理安全確保支援士/名称利用と匿名性

* 個人の見解であり、IPAや所属組織、法律専門家の見解ではありません

### 課題

情報処理安全確保支援士に関する記事を書こうと思って、ふと感じたのが、

```匿名で記事を書くということと、自身が情報処理安全確保支援士であることをその記事で表明することは、果たして両立するのか```

という課題感です。

### 個人的な結論

いろいろと脳内シミュレーションして、かつ、GPT君ともお話したりして、得た個人的な結論は、

```匿名で記事を書く場合、自身が情報処理安全確保支援士であることを表明するには慎重であるべき```

というものなので、私が情報処理安全確保支援士である（「登録」している）かどうかは内緒です（笑）

ちなみに試験自体には受かっています。（令和2年秋、ちょうど職場でVDI環境がデフォ、みたいな状況だったので、前日に参考書を読んで半分記念受験的な感じでギリギリ合格してました）

### 理由: 詐称に刑事罰が科されるということ

ご存じの方も多いかと思いますが、「情報処理安全確保支援士」は、独占的な業務(*1)は法律レベルでは存在せず、その「名称利用」が有資格者に与えられるメリットの柱となっている、名称独占資格です。

*1 有資格者だけが行える業務のこと。例えば、刑事事件の弁護人を行えるのは基本的に弁護士だけ。

「情報処理の促進に関する法律」にも、罰条を含め、名称利用の独占性が明示されています。

 - 第二十七条　情報処理安全確保支援士でない者は、情報処理安全確保支援士という名称を使用してはならない。
 - 第六十一条　次の各号のいずれかに該当する者は、三十万円以下の罰金に処する。
    - 一　第十九条第二項の規定により情報処理安全確保支援士の名称の使用の停止を命ぜられた者で、当該停止を命ぜられた期間中に、情報処理安全確保支援士の名称を使用したもの
    - 二　第二十七条の規定に違反した者


直接的にはこういう規定が法律にあるだけです。しかし、では、果たして、

```匿名で記事を書き、実名も登録番号も示さずに「私は情報処理安全確保支援士です」ということを表明した場合、この法律との関係でどのようなことが起こるリスクがあるのか```

ということを考えると、例えば、ですが、例えば、

```「おまわりさーん、実際にそうであることを立証もせず、『情報処理安全確保支援士』を名乗っている人をサイバー空間に発見しましたー！」```

というような通報をされた場合に、発信者情報開示請求とか、面倒なことになりかねない(笑) だって「犯罪の疑い」ということになってしまうので・・・（あくまで個人の、自分がそういうことに巻き込まれるのは嫌だな、という観点からのリスク抑止の観点からの見解であり、法律的にどのように取り扱われるのかは確信を持てません。）

そして、さらに弱気に考えてみると、そのような騒動の原因となる匿名の言動が、「情報処理の促進に関する法律」における「信用失墜行為の禁止」

 - 第二十四条　情報処理安全確保支援士は、情報処理安全確保支援士の信用を傷つけるような行為をしてはならない。

における「信用失墜行為」になりかねないのではないか（仮に私が情報処理安全確保支援士であった場合の話ですが。）

ということで、あくまで私自身に降りかかるリスク抑止の判断としては、繰り返しになりますが、

```匿名で記事を書く場合、自身が情報処理安全確保支援士であることを表明するには慎重であるべき```

という個人的な結論に、今のところはなっています。

### 将来

もしかしたら将来的に、匿名の情報発信と、何らかの国家資格者であることの立証をサイバー空間(*2)で両立できるような仕組み（PKI的な何か) が出来たりするのかなぁ、、、ということを思ったりしました。

*2 普段使わない単語ですが、IPA的な話題なのであえて使ってみました。
fedora xfceで2つめ以降のワークスペースの壁紙が変えられない場合

```shell
for ((i=1;i<4;i++))
do
xfconf-query -c xfce4-desktop -p /backdrop/screen0/monitorHDMI-2/workspace${i}/last-image --create -t string -s /usr/share/backgrounds/wallpaper2.jpg
done
```

`/usr/share/backgrounds/wallpaper2.jpg`
の部分は適当な画像で

以下コマンドでプロパティが見れる
```shell
xfconf-query -c xfce4-desktop -l
```
WindowsでのLinux開発環境構築

以下、概要のみ。
※細かいことはGoogleやAIで調べましょう。


## Windows Subsystem for Linux(以下、WSL)のインストール

※WindowsのPowerShellを管理者として実行

```
PS C:\windows\system32> wsl --install
```

```
PS C:\windows\system32> dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
PS C:\windows\system32> dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
```
コントロールパネルでも確認できる。
「プログラム」⇒「Windowsの機能の有効化または無効化」の画面
・仮想マシン　プラットフォーム
・Linux用Windowsサブシステム


## Linuxの更新プログラムのダウンロード、インストール

　https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi


## WSLのバージョン選択
```
PS C:\windows\system32> wsl --set-default-version 2
```
## Ubuntuを「Windowsストア」からインストール
※Windowsの検索窓に「Windowsストア」と入力
Windowsストアの検索窓から「Ubuntu」とにゅうりょｋ

結構待ってユーザ名、パスワードを入力する。
GolangのExcelizeを利用してセルの背景色のみを変更する

### 1.概要

Excelizeでは元となったExcelのテンプレート上のセルの色を変更しようとすると、フォントや罫線など他の設定も初期化されてしまい背景色のみを変更することができなかった。

> The cell color how to set? Can give a simple example? #254
> https://github.com/qax-os/excelize/issues/254

しかしissueでもあるようにExcelize v2.8.0からセルのフォントや罫線を保持した状態で背景色のみ変更できる様になった。
以下にサンプルとなるコードを記載する。

### 2.サンプルコード (名簿リストの内、不在者の列をグレーアウトする)
``` go:sample.go
if fuzai,ok := latest_fuzailist[item.KJID]; ok{
            print_fuzai := checkDateFlag(fuzai.GaisyutuDate,fuzai.KiinDate)
            _ = f.SetCellValue(mainSheet , fmt.Sprintf("C%d", print_row), print_fuzai)                        
            if print_fuzai == "不在" {
                for col := 'A'; col <= 'M'; col++ {
                    cell := fmt.Sprintf("%c%d", col, print_row) 
                    styleID, err := f.GetCellStyle(mainSheet,cell) //スタイルインデックスの取得
                    if err != nil {
                        panic(err)
                    }
                    style,err := f.GetStyle(styleID) //スタイル定義を取得する
                    if err != nil {
                        panic(err)
                    }
                    //スタイル定義に基づいてスタイルを変更または追加する ※今回は背景をグレーアウトする
                    style.Fill = excelize.Fill{
                        Type: "pattern",
                        Color: []string{"#C0C0C0"},
                        Pattern: 1,
                    }

                    newStyleID, err := f.NewStyle(style) //新しいスタイルを作成する
                    if err != nil {
                        panic(err)
                    }
                    _ = f.SetCellStyle(mainSheet, cell, cell, newStyleID) //変更したセルのスタイルを設定する
                }
            }
            
        }
```

### 3.まとめ
ExcelizeではExcel上のデータ処理は数多くの多くが可能であったが、罫線やフォントを設定しているセルの背景色を変更することが困難であった。
今回のアップデートではあらかじめ帳票としてテンプレートの罫線やフォントを指定した状態での帳票の背景色を変更できるようになった為、テンプレートでの活用の幅が広がると思うので知識を共有したい。
【待望】ついに登場！.NET 10.0 リリースまとめと注目ポイント

.NET開発者にとって待望の **.NET 10.0** がついに正式リリースされました！長らく待ち望まれていた新バージョンの詳細を、[公式サイト](https://dotnet.microsoft.com/ja-jp/download/dotnet/10.0)をもとに解説します。

---

## 🎉 .NET 10.0とは？

.NET 10.0は、Microsoftが提供する最新のクロスプラットフォーム開発フレームワークです。  
デスクトップアプリ、Webアプリ、クラウドネイティブ、モバイル、AI開発など幅広い領域に対応する「オールインワン」な進化を遂げました。

---

## 🔥 開発者が待ち望んでいた理由

- C# 13対応（次世代言語仕様の追加）
- パフォーマンス向上とメモリ効率の改善
- MAUI（.NET Multi-platform App UI）の強化
- BlazorのWebAssemblyパフォーマンス大幅改善
- クラウドネイティブ（コンテナ/マイクロサービス）への最適化強化

---

## 🚀 .NET 10の注目機能

### ✅ クロスプラットフォームの進化

- Windows / Linux / macOS すべてに対応
- ARM64（Apple M1/M2、Raspberry Piなど）でも動作安定性向上

### ✅ C# 13の新機能

- よりシンプルかつ安全な構文の追加
- ストリームライン化されたデータ操作、パターンマッチ強化など

### ✅ Blazor & MAUIの強化

- Blazor Server/Blazor WASMのパフォーマンス改善
- MAUIによるネイティブモバイルアプリの開発がよりスムーズに

### ✅ AIワークロード向け最適化

- .NET 10では、AI・機械学習ワークロードにも最適化
- ONNX RuntimeやML.NETとの親和性も強化

---

## 🛠 どんな開発者に最適？

- **エンタープライズ向けWebアプリ**開発者
- **クラウドネイティブ（Azure/Kubernetes）** に取り組むチーム
- **マルチプラットフォーム**で効率的に開発を進めたい方

---

## 📥 ダウンロードはこちら

公式サイトから各OS別にインストーラーが提供されています。

🔗 [.NET 10.0ダウンロード（Microsoft公式）](https://dotnet.microsoft.com/ja-jp/download/dotnet/10.0)

---

## 📝 まとめ

.NET 10.0は、モダンなアプリケーション開発に欠かせない機能が盛りだくさんの「決定版」と言えます。

**待った甲斐があった！**  
この機会に、ぜひ最新の.NETでプロジェクトを始めてみてはいかがでしょうか？

---

## 📚 参考

- [公式リリースノート](https://dotnet.microsoft.com/ja-jp/download/dotnet/10.0)
- [Microsoft Learn - .NET 開発](https://learn.microsoft.com/dotnet/)
【選定理由】なぜMudBlazorを採用するのか？Blazor UIライブラリ比較

Blazorアプリを開発する際に、多くのUIライブラリの中から **MudBlazor** を選定するケースが増えています。本記事では MudBlazor を採用する理由を明確に解説します。

## 🎯 MudBlazorとは？

MudBlazorは、Blazor向けに最適化されたオープンソースの**Material Designベース**のUIライブラリです。Blazor Server / WebAssemblyの両方に対応しており、Microsoft公式もドキュメントで取り上げています。

---

## 🔍 MudBlazorを選定する理由

### 1. **Blazorに最適化されている**

- C#のみでUI実装が完結（JavaScript依存が少ない）
- Blazorのライフサイクルや構造に沿ったコンポーネント設計

### 2. **Material Designベース**

- GoogleのMaterial Design準拠のデザインガイドライン
- 一貫したUX/UIをすぐに導入可能

### 3. **豊富なコンポーネント**

- DataGrid, Dialog, Snackbar, Tabs, Drawerなど一般的なUI部品がすぐに利用可能
- Form系、表、ナビゲーション系まで幅広く網羅

### 4. **カスタマイズ性が高い**

- SCSSやテーマ機能による柔軟なスタイル変更が可能
- 各コンポーネントがCSSクラスやスタイル指定に対応

### 5. **活発なコミュニティと更新頻度**

- GitHubでのスター数、Issue対応、PRのスピードが速い
- MudBlazor公式サイトのドキュメントも充実

---

## 🔄 他ライブラリとの比較

| ライブラリ名           | 特徴                                 |
|------------------------|--------------------------------------|
| MudBlazor              | Material Design準拠、Blazor特化      |
| Radzen Blazor          | 商用利用は有償、WYSIWYG対応          |
| Syncfusion Blazor      | 商用向け機能が充実、有料プラン有     |
| Blazorise              | Bootstrap系でカジュアルなUI          |

MudBlazorは **無料・OSS** かつ **高品質** な Material Design UI を手軽に導入できるのが強みです。

---

## 💡 こんなプロジェクトに最適

- 内製業務システム（ダッシュボード、管理画面）
- SPA型のBtoBアプリケーション
- デザイナー不在の小規模プロジェクト

---

## 📝 まとめ

MudBlazorは、**Blazor×Material Design**を軸に、  
「開発スピード」と「見た目の良さ」を両立したい現場に最適です。

まずは公式サイトで動作確認してみるのがおすすめです。

---

## 📚 参考リンク

- [MudBlazor公式](https://mudblazor.com/)
- [GitHub MudBlazor](https://github.com/MudBlazor/MudBlazor)
- [Blazor公式ドキュメント](https://learn.microsoft.com/aspnet/core/blazor/)
【Rails】セッションリプレイ攻撃を防ぐ方法


# はじめに
こんにちは。アメリカに住みながら独学でエンジニアを目指している taira です。
現在、Railsチュートリアルを使用して学習を進める中で、セッションリプレイ攻撃への対策方法について疑問を持ちました。
そこで、教材に掲載されていたサイトを参考にしながら、自分なりに情報を整理してみました。

## セッションリプレイ攻撃とは
セッションリプレイ攻撃（Session Replay Attack）とは、攻撃者がユーザーとサーバー間の正規通信を盗聴し、その通信内容（特に認証情報やセッション識別子）を記録・保存したうえで、後から再送（リプレイ）することで不正にシステムへアクセスする攻撃手法です。

## なぜ起こるのか
セッションリプレイ攻撃が起こる主な原因として、認証手段をユーザーIDのみで済ませている点が挙げられます。ユーザーIDは単純な数字（たとえば `user_id = 3` など）であるうえ、一度設定すると変更が行われにくい値です。もし cookie が盗まれ、その中にユーザーIDが含まれていれば、ユーザーIDを変更しにくい（もしくは変更しない）ため、対応策がなくなってしまいます。

## `user_id`を認証に使わないという選択肢は？
私が疑問に思ったのは、「ユーザーごとに都度発行されるトークンを使えばいいのではないか」という点でした。しかし `user_id` は主キーとして一意であるため、`User.find` などを使用したデータベース検索の高速化に役立ちます。そのため、システムの効率を考慮すると、`user_id` を認証やユーザー判別に活用するメリットも大きいのです。

## 対策方法
そこで有効なのが、`user_id` に加え、ログインするたびに発行される `session_token` を組み合わせる方法です。以下の例のように、ブラウザを閉じると削除される `session_token` を利用します。

```ruby
def log_in(user)
    session[:user_id] = user.id
    session[:session_token] = user.session_token  # 追加
end

def current_user
    if (user_id = session[:user_id])
        user = User.find_by(id: user_id)
        if user && session[:session_token] == user.session_token  # 追加
            @current_user = user
        end
    elsif (user_id = cookies.encrypted[:user_id])
        user = User.find_by(id: user_id)
        if user && user.authenticated?(cookies[:remember_token])
            log_in user
            @current_user = user
        end
    end
end
```

モデル側では `session_token` メソッドを利用してハッシュ値を生成する実装が想定されています。これにより、`current_user` の認証時に `session_token` が一致しない限りログイン処理が行われないため、セッションリプレイ攻撃を防ぐことが可能です。

# まとめ
セッションリプレイ攻撃を防ぐには、単純な `user_id` のみの認証だけでなく、都度発行されるトークンを組み合わせて使用することが重要です。効率性の面で `user_id` を使いつつ、セキュリティ対策としては `session_token` を活用することで、システム全体の安全性を向上できます。

## 参照記事
https://techracho.bpsinc.jp/hachi8833/2023_06_02/130443
M5Stack Echo Baseを使ってサンプリングもどき

# やりたいこと

Echo BaseはマイクとスピーカーをATOMに追加するモジュール。フィールドレコーディングとか楽しめそう、ということで録音して再生するアプリを作りたい。

https://www.switch-science.com/products/10193?variant=44381254746310

## チュートリアルを読もう

Echo Baseのチュートリアルでサンプルコードが公開されてます。これを改造して録音後も任意のタイミングで再生できるようにしてみる。

https://docs.m5stack.com/en/arduino/projects/atomic/atomic_echo_base

### ライブラリでできること

```C: 録音
#define RECORD_SIZE (1024 * 96)
M5EchoBase echobase(I2S_NUM_0);
static uint8_t *buffer = nullptr;

// もろもろ初期化したらこれ一発でレコーディング
echobase.record(buffer, RECORD_SIZE);
```

```C: 再生
// これ呼べば再生開始
echobase.play(buffer, RECORD_SIZE);
```

## ちょっと改造

このチュートリアルではATOMS3Rをクリックするとレコーディングを開始して即再生を行っている。とりあえずボタンのジェスチャーには長押しとかもあるので、長押しで録音開始、シングルクリックで再生するように改造してみる。
おまけでレコーディング開始前にスリーカウントのカウントダウンを挟んだ。即録音開始するとクリック音も録音されてしまうのでそれの回避策です。
あとレコーディングしていない状態では再生できないようにブロックしてある。いきなり再生するとノイズが再生されるからね。

```C: 修正後のコード
#include <M5Unified.h>
#include <Arduino.h>
#include <M5EchoBase.h>

#define RECORD_SIZE (1024 * 96)
M5EchoBase echobase(I2S_NUM_0);
static uint8_t *buffer = nullptr;
bool recorded = false;

void setup() {
  M5.begin();
  M5.Display.setFont(&fonts::FreeMonoBold9pt7b);
  Serial.begin(115200);

  echobase.init(16000, 38, 39, 7, 6, 5, 8, Wire);

  echobase.setSpeakerVolume(60);
  echobase.setMicGain(ES8311_MIC_GAIN_6DB);

  buffer = (uint8_t *)malloc(RECORD_SIZE);
  if (buffer == nullptr) {
    while (true) {
      M5.Display.println("Failed to allocate memory :(");
      Serial.println("Failed to allocate memory :(");
      delay(1000);
    }
  }

  Serial.println("EchoBase ready, start recording and playing!");
  M5.Display.println("Hold to Record & Play.");
  M5.Display.println("Click to Playback.");
}

void loop() {
  M5.update();
  if (M5.BtnA.wasHold()) {
    M5.Display.fillScreen(BLACK);
    M5.Display.setCursor(0, 0);
    M5.Display.println("Countdown");

    // waiting 3 count
    M5.Display.print("3, ");
    delay(1000);
    M5.Display.print("2, ");
    delay(1000);
    M5.Display.println("1");
    delay(1000);

    M5.Display.setTextColor(RED);
    M5.Display.println("Recording");
    // Recording
    echobase.setMute(true);
    delay(10);
    M5.Display.setTextColor(WHITE);
    echobase.record(buffer, RECORD_SIZE);
    delay(100);
    recorded = true;

    M5.Display.println("Playing");
    // Playing
    echobase.setMute(false);
    delay(10);
    echobase.play(buffer, RECORD_SIZE);
    delay(100);
    M5.Display.println("Done");
  } else if (M5.BtnA.wasClicked()) {
    if (recorded) {
      M5.Display.fillScreen(BLACK);
      M5.Display.setCursor(0, 0);
      M5.Display.println("Playing");
      // Playing
      echobase.setMute(false);
      delay(10);
      echobase.play(buffer, RECORD_SIZE);
      delay(100);
      M5.Display.println("Done");
    }
  }
}
```
Pythonでログを出力する(コードスニペット)

```py
import logging

# ログの設定
logging.basicConfig(
    filename="python_output.log",   # ログファイル名
    level=logging.INFO,             # ログレベル
    format="%(asctime)s - %(levelname)s - %(message)s"
)

# ログに出力
logging.info("これはログ出力です")
logging.error("これはエラー出力です")
```
Agentforceの価格


+ [【2025年最新版】Salesforceの価格 | 各製品の価格や機能を一覧](https://www.strh.co.jp/knowledge/salesforce-price)
+ [Agentforceの価格](https://www.salesforce.com/jp/agentforce/pricing/)

既存のSalesforceのお客様は、Agentforceを無料で開始できます。Salesforce Foundationsでは、現在契約していないSalesforceのCloud製品の無料プランを利用できるようになります。これには、Agentforceも含まれます。会話ごとの従量課金制です。活用例を思い浮かべながら、まずは始めてみましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/dbf83d89-48f7-4631-b9d2-b35377226618.png)


+ AIエージェントの構築方法は？

Agent BuilderでAIエージェントを構築できます。既存のSalesforce Platformツールを使用して、標準およびカスタムのトピックやアクションを作成できます。信頼できるエンタープライズデータにもとづいたプロンプトを使用できます。Flowsを使用して、あらゆるシステムに自動化を適用できます。MuleSoft APIコネクターを使用して、AIエージェントを任意のシステムに接続できます。そして最後にApexとJavascriptを使用して、AIエージェント用のカスタムコードやビジネスロジックを作成できます。


# さらに

https://www.strh.co.jp/knowledge/salesforce-agentforce

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/aa8d56d0-c845-40ca-bcab-bdbdf323c6bb.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/fe7e7973-41f0-4332-a525-9dd440659312.png)
【実践】Blazor/MudBlazorのBasePath（ベースパス）対応ガイド

Blazorアプリをサブディレクトリにデプロイする際の **BasePath（ベースパス）** 対応について簡潔にまとめます。

## 🎯 BasePathとは？

アプリケーションがホストされる基準パスのことです。

例：
- ルート： `https://example.com/`
- サブディレクトリ： `https://example.com/myapp/`

---

## 🔧 appsettings.jsonにBasePathを記述

`appsettings.json` に **BasePath** を設定しましょう。

---

## 🧩 App.razorでの `<base>` タグ設定

`<base>` タグに **appsettingsで設定したBasePath** を指定します。

---


## ⚠️ 開発ルール：相対パスで統一

アプリケーション内のナビゲーションやリンクは **相対パスで統一** しましょう。

---

## 🚩 よくあるトラブル回避

- `<base>` の記述忘れに注意
- BasePathの末尾に `/` を付けるようにする
- 全コンポーネントで絶対パスを避ける

---

## 📚 参考リンク

- [Blazor Base Path Handling](https://learn.microsoft.com/aspnet/core/blazor/host-and-deploy/?view=aspnetcore-8.0&tabs=visual-studio#base-path-configuration)
- [MudBlazor公式ドキュメント](https://mudblazor.com/components)

---

## 📝 まとめ

- `appsettings.json` に BasePath を設定する
- `<base>` タグに適切に設定する
- アプリ全体で相対パスを意識する

これでサブディレクトリ配下へのデプロイでも安全に動作します！
Bolt.new使うぞ

## はじめに
今月に入社してエンジニアとして、レベルを上げていきたいと日々奮闘しており、
AIエージェントを使いこなすのは次のデファクトスタンダードになると聞いて、やるしか！ってなってます。

今日はbolt.newについていろんなサイトを参考にして、自分なりにアウトプットをさせていただきます。

## Bolt.newとは
bolt.new（ボルト）とは、StackBlitz社が開発した、ブラウザベースの開発環境を提供しているテキストのみでフルスタックアプリケーションが作れるAIツール。

## まず無料で始められる！
無料で始められて、自然言語でアプリを作れてしまうなんて最高すぎます😇
無料の要件としては、
- 回数制限が厳しい
- Claude 3.5 Sonnetの使用
- StackBlitz Personalの全機能

有料版もチームで使うもので5000円くらいなのでコスト面もいい感じです。

## フレームワークが豊富に選択可能！
React、Vue、Angular、Next.jsなど、人気のフレームワークを使用できます。
私の好きなVueもいますし、嬉しいですね。

## その他

その他の機能として、バグ修正機能、ボタン1つでデプロイができてしまいます👭✨


ちょっと、説明はここまで！

みなさん今から触りに行こう！解散！！


## 参考サイト
https://weel.co.jp/media/innovator/bolt/

https://shift-ai.co.jp/blog/10383/

https://rozetta-square.jp/knowledge/9090/
Goのポインタでつまったところ

# はじめに
Goのポインタでつまったところがあったので、整理も兼ねて記事にします
具体的には、`デリファレンス`という動きについて、つまずいたので、もし聞いたことがない方には参考になると思います。

# Goのポインタについて
整理のため、Goのポインタについてまとめます

### 宣言と使用方法
```go
// 変数
var str string
str = "test"
fmt.Println(str) // test

// ポインタ型の変数
var strp *string
// 変数のポインタを格納
// &をつけると変数のアドレスが取得できるのでそれをポインタ型の変数に格納する
strp = &str

// ポインタ型の変数を普通に出力するとアドレスが出力される
fmt.Println(strp) // 0xc000012090のような形式

// ポインタ型の変数に*をつけると中身が取得できる
// これをデリファレンスという
value := *strp
fmt.Println(value) // test
```

### 値の書き換え
```go
var str string
str = "test"

var strp *string
strp = &str

// 値を書き換える場合もデリファレンスを使い、中身にアクセスする
*strp = "new"
fmt.Println(*strp) // new

// strpは、strのアドレスを代入したため、strpはstrと同じアドレスとなっている
// アドレスが同じなので、strpを書き換えるとstrも変わる
fmt.Println(str)   // new
```

### ポインタ型宣言時はnilになる
つまったポイント１つ目です。
`*strp = "new"`で、値を代入できるのかと知り、以下のコードを実行するとエラーになりました。

```go
var strp *string
*strp = "new"
fmt.Println(*strp)
```

理由は、`var strp *string`を宣言時は、ポインタ型変数はnilになります。
したがって、*strpでアクセスしようとすると、`invalid memory address or nil pointer dereference`というエラーになります

以下のようにすると、エラーは解消します

```go
var strp *string
// newでメモリを確保する
strp = new(string)
*strp = "new"
fmt.Println(*strp)
```

### 構造体では自動でデリファレンスされる
つまったポイント2つ目です。
```go
type Person struct {
	Name string
	Age  int
}

var person Person
person = Person{
	Name: "aaa",
	Age:  12,
}

var personp *Person
personp = &Person{
	Name: "aaa",
	Age:  12,
}
```

上記のように構造体でポインタを試そうとしました。
*変数名で、中身を取得できるので、*personp.Nameのような形で出力しようとするとエラーとなりました。
理由は、構造体の場合は自動でデリファレンスされるので、*personp.Nameにしなくてもよいみたいです。(invalid operation: cannot indirect personp.Name (variable of type stringというエラーが出てしまいます)

```go
type Person struct {
	Name string
	Age  int
}

var person Person
person = Person{
	Name: "aaa",
	Age:  12,
}

var personp *Person
personp = &Person{
	Name: "aaa",
	Age:  12,
}

fmt.Println(person.Name)  // aaa
// 自動デリファレンスされるので*は不要
// fmt.Println(*personp.Name)
fmt.Println(personp.Name) // aaa
```
Gmail 日本語から日本語の誤訳？対応

老爺心的手控 #1

## 概要

- Gmail で件名や本文が改変される
- 自動翻訳に設定 + \[メッセージの一部が表示されています\]状態で省略表示で発生

## 発生を確認した環境

- Windows 11 + Chrome134 + URL：`https://mail.google.com/mail/～`
- Windows 11 + Firefox + URL：`https://mail.google.com/mail/～`
- Android 12 + Gmail アプリ 2025.03.09.737834555.Release

## 発生日

2025 年 3 月 18 日(月)頃～

## 現象

### Gmail 誤訳表示（と思われる）と正しい表示の比較例

例示メールは、サーバー運営会社からの問い合わせフォームの自動返信機能悪用対策依頼  
（誤り方が絶妙すぎてスパムにしか見えない）

### 誤表示

![誤表示：件名が繰り返し表示された](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/561018/d49f5c9b-0f2d-4e4c-b42c-a085b1537b5b.png)
![誤表示：無効が有効に変更された](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/561018/784c232a-165f-4405-8cc3-19a4d5fdf890.png)
![誤表示：「当選率で全員に送信」に変更された](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/561018/fdb8fac6-8111-4a80-b966-c93db996b52a.png)

### 正しい表示

![正しい表示：件名](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/561018/3e67e19b-9615-43cd-b6a8-172bb31e010e.png)
![正しい表示：正しくは無効](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/561018/da3cc15d-bdce-4fcd-bde6-319dad7672ed.png)
![正しい表示：正しくは受取可否に限らず送信](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/561018/d21ca756-b7b6-469e-bf6c-b496159d6d8f.png)

## 対処方法

### 対処療法

- 「メッセージ全体を表示」をクリックして全体表示する  
   \[メッセージの一部が表示されています\] の表示がないメールは改変されない

- 印刷する
  印刷は全体表示されるので改変されない

### 恒久対策

- 自動翻訳設定を解除する  
   Gmail が日本語から日本語に自動変換して誤訳？している様なので翻訳しなければ改変されない
レアゾン・ホールディングス 2024新卒エンジニアフロントエンド研修 - 基礎力を高めるHTML・CSSからReactまでの学び -

こんにちは！2024新卒menu事業部フロントエンドエンジニアの櫻井です。
大学で車の設計を学んでいましたが、興味が持てず2年間休学をしてWebサイト制作の個人事業主を経験しました！
その後「世界一の企業へ」というVisionに惹かれレアゾン・ホールディングスへ新卒入社し、様々な技術を学ぶ研修を受けました。
今回の記事では、その研修の中でも特にフロントエンド研修についてご紹介させていただきます。

## 研修の概要
研修の概要はオウンドメディアの記事で詳しく紹介していますので、こちらからご覧ください。

https://media.reazon.jp/special/NewGraduate_engineer

## フロントエンド研修の概要

私たちが受講したフロントエンド研修では、 以下のステップを通して基礎から応用までの技術を学びました

1. HTML・CSSの学習：会社のHPを作成（1日目）
2. ブラウザの基本機能とHTTPプロトコルの理解（2日目 ~ 3日目）
3. Reactの学習：ECサイトを作成（4日目 ~ 7日目）

## フロントエンド研修の詳細
:::note info
新卒研修では、ゲーム開発志望やPM職志望のエンジニアも参加していたため、フロントエンド研修は基礎的な部分からスタートしました。
:::

### HTML・CSSの学習：レアゾン・ホールディングスのHPを作成（1日目）

最初に学んだのは、HTMLとCSSの基礎です。これにより、どのようにWebページが構築され、ブラウザ上で見た目が作り上げられるのかを理解することができました。
HTMLでは、各要素の役割やセマンティックなマークアップを重視し、正しいHTMLの書き方に慣れることを目的としました。
また、CSSでは、レイアウトの調整やレスポンシブデザインを学び、モバイルやデスクトップなど異なるデバイスでの最適な表示方法に焦点を当てました。
この段階で、実際にレアゾン・ホールディングスのHPを模倣するようなWebサイトを作成することで、実践的なスキルを身につけることができました。

**▼研修で模倣したWebサイト**

https://reazista.co.jp/

### ブラウザの基本機能とHTTPプロトコルの理解（2日目 ~ 3日目）
次に、ブラウザの基本機能やHTTPプロトコルの理解に進みました。特に、ブラウザがどのようにしてHTML、CSS、JavaScriptを読み込み、レンダリングするか、また、HTTPリクエストとレスポンスのメカニズムを深く学びました。ここでは、通信の仕組みを理解するために、実際にブラウザの開発者ツールを使って、ネットワークの動きを確認しました。こうした技術を学ぶことで、Webアプリケーションがどのようにしてデータを取得し、ページを動的に更新するかを体感することができました。特に非同期通信に関しては、JavaScriptの`fetch`を使ってAPIにデータをリクエストし、ページが更新される過程を実際にコードを書いて学びました。


## Reactの学習：ECサイトを作成（3日目 ~ 7日目）
研修の後半では、フロントエンドのフレームワークとしてReactを集中的に学びました。
まずはReactの基本的なコンセプトであるコンポーネントベースの設計や、hooksの使い方、それを用いた動的なUI構築に挑戦しました。
また、TypeScriptを使った型宣言や、フロントエンドで重要な非同期処理をReactと組み合わせて学ぶことで、より高度なアプリケーション開発のスキルを習得しました。

**▼実際に作成したECサイト**
![20240917222218.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3980570/53df236b-5b36-4057-98e1-f629dfb6d3fe.png)

### 技術的なお話し
私は現在、menu事業部のフロントエンジニアとして、React Nativeを中心に業務を行っています。
研修で学んだReactは、実務でも頻繁に活用しています。
特に、業務で取り組んでいるmenu事業のフロントエンドでは、複雑な処理や、リアルタイムなデータ更新を要求される場面が多いです。
この際に、研修で学んだ`useMemo`や`useCallback`などを適切に使用してパフォーマンスを最適化しています。

HTTPプロトコルや非同期通信に関しても、研修で学んだ知識が実務に直結しています。menu事業部では、APIと非同期通信を通して行い、バックエンドとの連携が多く発生します。
特に、非同期通信時のエラーハンドリングは、研修で学んだ内容をベースにより高度な設計を考えるきっかけになり、APIとの通信がより効率的かつスムーズに行えるような、ユーザーエクスペリエンスの向上に貢献しています。

:::note info
このように、研修で学んだ基礎知識が実務での応用力や問題解決力に直結していることを実感しています。
技術の表層的な理解ではなく、内部でどのように動いているかを深く理解することで、効率的でパフォーマンスの高いコードを書くことができるようになりました。
:::
### まとめ
今回の研修を通して、基礎から応用まで一貫して学ぶことができ、特にフロントエンドの技術が現在の業務に直結していることを強く感じました。
今後も、基礎を大切にしつつ、新しい技術にチャレンジしていきたいと思います！

### **▼採用情報**
レアゾン・ホールディングスは、「世界一の企業へ」というビジョンを掲げ、「新しい"当たり前"を作り続ける」というミッションを推進しています。

現在、エンジニア採用を積極的に行っておりますので、ご興味をお持ちいただけましたら、ぜひ下記リンクからご応募ください。

https://recruit.reazon.jp/
業務委託の面接で使える逆質問を多く挙げますね！


---

## 【業務内容について】
1. 業務委託でご依頼いただく背景や課題について詳しくお聞かせいただけますか？
2. 今回の業務において、特に重要視されているポイントはどこでしょうか？
3. 成果物の品質基準や評価指標はどのように設定されていますか？
4. 業務開始後、どのような流れで進捗管理や確認を行うご予定でしょうか？
5. 業務委託先の他のメンバーとの連携やコミュニケーション体制について教えていただけますか？
6. 作業中に想定外の問題が発生した場合、どのようなフローで対処されますか？
7. 今回の業務を通じて達成したい貴社のゴールや期待されるアウトプットを具体的に教えてください。

---

## 【期待値の確認】
8. 私に特に期待されていることや、貢献を望まれているポイントはありますか？
9. 過去に外部パートナーに依頼した際の成功事例や失敗事例などがあれば参考にお聞かせください。
10. 業務を進める上で、最も避けたいこと、注意点などはありますでしょうか？

---

## 【環境・体制について】
11. 作業環境（システムやツール、コミュニケーション手段等）で推奨されているものはありますか？
12. 貴社内の担当者様はどのような体制で私をサポートいただけるのでしょうか？
13. 質問や確認事項が発生した際の問い合わせ窓口や対応スピードの目安を教えてください。
14. 業務委託契約において、特に重視される守秘義務やセキュリティ管理に関するルールはありますか？

---

## 【期間・報酬条件について】
15. 契約期間やその後の更新予定はどのようになっていますか？
16. 成果物の提出スケジュールや期限に変更が生じる可能性がある場合、どの程度柔軟な対応が可能ですか？
17. 報酬条件に関して、定期的なレビューや見直しの機会は設けられていますでしょうか？
18. 成果や評価によって契約内容（期間・報酬）が変動する仕組みはありますか？

---

## 【成果・評価フィードバック】
19. 業務開始後、定期的なフィードバックや進捗報告の機会はどのように設定されていますか？
20. 私のパフォーマンスや成果をどのように測定され、評価されますか？
21. より良い成果を出すために、委託業務中に私に求められる報告方法や頻度はありますか？

---

## 【貴社・チームについて】
22. 業務を通じて特に重視されている貴社の理念や価値観について教えていただけますか？
23. 社内やプロジェクトチームの雰囲気・文化・働き方の特徴を教えていただけますか？
24. 私のような外部パートナーとの連携で、過去に問題になったこと、改善されたことなどはありますか？

---

## 【将来的な関係構築について】
25. 今回のプロジェクトが成功した場合、今後も継続的にお仕事をお願いしていただける可能性はありますか？
26. 長期的に関係を築く上で、貴社が業務委託パートナーに求める要素や条件をお聞かせください。

---

状況や会話の流れに合わせて、必要なものを選んでお使いください。
⚠️ 機械学習プロジェクトの落とし穴：よくある失敗とその回避策【現場で効く具体例付き】


## はじめに

機械学習（ML）プロジェクトは、理論やアルゴリズムの話だけでは終わりません。  
**「実際に成果が出るかどうか」**が最も重要なポイントです。

しかし、現場では「精度が高いのに使われない」「効果が実感できない」といった声をよく聞きます。  
本記事では、そんな**よくある失敗パターン3選**を深掘りし、それぞれの**原因・背景・対策**を解説します。

---

## 💣 失敗例①：モデル精度は高いのに売上が伸びない

### 🧨 どういうこと？
モデルは高精度（例えば、F1スコア 0.93）なのに、実際にはビジネス成果（売上や利益）が上がっていないパターン。

### 🔍 主な原因
- KPIが**技術指標のみ（Accuracy, AUCなど）**で、**ビジネス指標（売上・利益・CVRなど）**とつながっていない
- モデルが良くても**ユーザーに使われていないUI設計**
- **モデルの導入範囲が限定的**で、インパクトが小さい

### 💡 回避策
- 初期のKPI設計時に、**技術KPIとビジネスKPIの両方**を設定
- 例：  
  - 技術KPI：クリック率予測モデルのAUC ≥ 0.85  
  - ビジネスKPI：クリック率（CTR）が5%以上向上すること
- A/Bテストを実施し、**モデル導入前後の売上やCVRの変化を検証**する
- ステークホルダーと「**ビジネスとしての成功条件**」を事前にすり合わせる

---

## 💣 失敗例②：中間KPIは達成されたのに現場で使われない

### 🧨 どういうこと？
モデル自体の性能は満たしているのに、**業務オペレーションに導入されていない／意思決定に使われていない**。

### 🔍 主な原因
- **評価指標が現場の肌感と合っていない**
  - 例：Recallを上げたが、False Positiveが多くて現場が使いづらい
- 現場のKPI（現実のオペレーション上の数値）と開発側のKPIが乖離
- 評価レポートが**技術的すぎて理解されていない**

### 💡 回避策
- **初期段階で現場ヒアリング**を行い、使いやすさ・業務への影響をKPI設計に反映
- 例：  
  - 技術者視点：Recall ≥ 0.85  
  - 現場視点：誤検出率 ≤ 5%、アラート件数が1日10件以内
- モデル出力を**業務プロセスにどう組み込むか**も設計する（通知、UI表示、優先順位づけなど）
- 評価レポートは**非エンジニアにも伝わる形**で共有（ビジュアル化、サンプルケース付き）

---

## 💣 失敗例③：目標が曖昧なまま始めてしまった

### 🧨 どういうこと？
「とりあえずAI導入してみよう」と始めたが、結局何が成功なのか分からず、時間と予算だけが消化されて終わる。

### 🔍 主な原因
- **KGI（最終成果指標）とKPIの未設定**
- モデル完成がゴールになっていて、**運用や活用方法が定まっていない**
- ステークホルダー間で**目的の認識にズレ**がある（例：開発チームは効率化が目標、現場は品質向上を期待）

### 💡 回避策
- プロジェクト開始前に「**何を達成すれば成功なのか**」を言語化（KGIの定義）
- 例：  
  - KGI：返品率を20%削減  
  - KPI：不良品検出モデルのPrecision ≥ 0.9、処理時間 ≤ 5秒
- **KPI設計シート（Notion, Excel等）**でゴールを明文化し、全関係者と共有
- プロジェクト進行中も**定期的にKPIの妥当性を見直す**

---

## 🔄 よくある失敗 → 改善サイクルまとめ

| 失敗例 | 主な原因 | 解決策 |
|--------|----------|--------|
| モデル精度は高いのに売上が伸びない | 技術KPIのみでビジネス貢献が不明確 | 技術KPI＋ビジネスKPIをセットで定義、A/Bテスト導入 |
| 中間KPIは良いのに使われない | 現場との認識差、業務への影響未考慮 | 現場と評価軸を合わせる、運用導線を作る |
| 目標が曖昧なまま進めた | KGI・KPI未設定、方向性のブレ | 目標定義シートで目的・指標・スコープを明文化 |

---

## ✅ まとめ

- 機械学習プロジェクトの成功は「精度の高さ」だけでは測れない
- 技術KPIとビジネスKPIの**バランス設計**が超重要
- 「精度が良くても使われない」を防ぐには、**現場との共通認識**と**導入のしやすさ**がカギ
- 目標の曖昧さはプロジェクト全体を迷走させる。**KGI・KPIの明文化と共有**は初期フェーズの最優先タスク

---

## 💬 最後に：KPIは“測るもの”ではなく“導くもの”

KPIを「結果を評価するための道具」とだけ考えると、後手に回ってしまいます。  
本質的には、KPIとは**プロジェクトを正しい方向に導くためのコンパス**です。

---

必要であればこの内容を  
📌 **Notion記事テンプレート**  
📊 **プレゼン資料（PowerPoint形式）**  
📎 **提案書（PDF）**  
などに変換することも可能です！ご希望があれば遠慮なくお知らせください。
【SQLアンチパターン】「素朴ツリー」の落とし穴とスマートな解決策

## ツリー構造を管理するために `parent_id` を使っていませんか？

データベースで **カテゴリや組織のツリー構造** を管理する場合、  
よく `parent_id` を使った **「素朴ツリー（Naïve Trees）」** という設計が採用されます。  

しかし、この方法には **検索・更新・削除のパフォーマンスが悪くなる問題** があります！  
本記事では、「素朴ツリー」の問題点と、より効率的な代替手法を紹介します。  

## 素朴ツリーの構造

ツリー構造を表現するための典型的なテーブル設計。

```sql
CREATE TABLE categories (
    id SERIAL PRIMARY KEY,
    name TEXT NOT NULL,
    parent_id INTEGER REFERENCES categories(id)  -- 親カテゴリのID
);
```

データの例

id | name | parent_id  
----|------|-----------  
1 | 家電 | NULL  
2 | テレビ | 1  
3 | 冷蔵庫 | 1  
4 | 4Kテレビ | 2  

このように、`parent_id` を使ってツリー構造を表現する。

## 素朴ツリーの問題点

### 階層の深い検索が難しい

例えば、「家電」カテゴリ以下の全ての子カテゴリを取得したい場合、通常のSQLでは1回のクエリでは取得できない。

良くない方法（親→子を1段ずつ取得）

```sql
SELECT * FROM categories WHERE parent_id = 1;  -- "家電" の子カテゴリ（テレビ, 冷蔵庫）
SELECT * FROM categories WHERE parent_id = 2;  -- "テレビ" の子カテゴリ（4Kテレビ）
```

この方法では、ループを回して何度もクエリを発行しなければならず、パフォーマンスが悪い。

### 更新・削除が面倒

例えば、「テレビ」カテゴリを削除する場合、子カテゴリである「4Kテレビ」も削除しないと整合性が取れない。

良くない削除処理

```sql
DELETE FROM categories WHERE id = 2;  -- "テレビ" を削除
DELETE FROM categories WHERE parent_id = 2;  -- "4Kテレビ" も削除
```

この方法では、以下の問題が発生する。

- 子カテゴリの削除を手動で行う必要がある
- データの不整合が発生する可能性がある
- ツリーが深くなると削除処理が複雑になる

## 素朴ツリーの代替案

### 経路列挙モデル（Path Enumeration）

各ノードにツリーのパスを文字列として保存する方法。

```sql
CREATE TABLE categories (
    id SERIAL PRIMARY KEY,
    name TEXT NOT NULL,
    path TEXT NOT NULL  -- 例: "1/2/4"
);
```

例として、「4Kテレビ」の `path` は `"1/2/4"` となる。

この方法のメリットとデメリットは以下の通り。

メリット:
- SQLの `LIKE` を使って簡単にツリー全体を検索できる（例: `LIKE '1/%'` で家電以下を取得可能）

デメリット:
- `path` を更新する際、すべての子ノードの `path` も更新しなければならない

### 閉包テーブルモデル（Closure Table）

すべての親子関係を別テーブルで管理する方法。

```sql
CREATE TABLE category_hierarchy (
    ancestor INTEGER NOT NULL,
    descendant INTEGER NOT NULL,
    PRIMARY KEY (ancestor, descendant)
);
```

この方法のメリットとデメリットは以下の通り。

メリット:
- 階層の検索や削除が効率的
- `JOIN` を活用してツリー全体を簡単に検索できる

デメリット:
- 追加時に `category_hierarchy` に複数レコードを挿入する必要がある

## まとめ

| モデル | 特徴 | メリット | デメリット |
|--------|------|----------|------------|
| 素朴ツリー | `parent_id` を使う | シンプルで直感的 | 階層検索や削除が大変 |
| 経路列挙 | `path` にツリー構造を保存 | `LIKE` で検索しやすい | 更新時に`path`を変更する必要がある |
| 閉包テーブル | 別テーブルで親子関係を管理 | 階層の検索・削除が簡単 | データ追加時に複数の挿入が必要 |

## まとめ
小規模なデータなら素朴ツリーでも問題ないが、大規模なツリー構造を扱う場合は `経路列挙` や `閉包テーブル` を検討すべき。

データの用途に応じて適切な設計を選ぶことが重要。
機械学習プロジェクトにおけるKPIの設定


## 目次（続き）

1. 機械学習プロジェクトの全体像
2. KPIとは何か？機械学習プロジェクトでの意味
3. KPI設定のステップと具体例
4. 機械学習プロジェクトの始め方：フェーズ別ガイド
5. よくある失敗とその回避策
6. 成功事例とKPIの結びつき
7. おわりに：KPIは「測る」だけでなく「導く」ためのもの

---

## 1. 機械学習プロジェクトの全体像

機械学習プロジェクトは、以下のようなフェーズで構成されます：

1. **ビジネス課題の特定**
2. **データ収集と前処理**
3. **モデル選定と構築**
4. **評価とチューニング**
5. **デプロイと運用**
6. **継続的な改善（MLOps）**

### なぜKPIが重要か？

MLプロジェクトは「精度が高ければOK」ではなく、**ビジネスインパクト**（利益向上、コスト削減、ユーザー体験向上など）を生むことが本来の目的です。KPIがなければ「成功の定義」が曖昧になり、プロジェクトの方向性もぶれてしまいます。

---

## 2. KPIとは何か？機械学習プロジェクトでの意味

**KPI（Key Performance Indicator）**とは、プロジェクトが目指す目標に対して「進捗や達成度を数値で可視化する指標」のことです。

### 通常のKPIとの違い

| 一般的なビジネスKPI | 機械学習プロジェクト特有のKPI |
|----------------------|------------------------------|
| 売上・利益率・LTVなど | モデル精度、再現率、AUCなどの評価指標 |
| ユーザー数の増減 | 実運用後のクリック率や解約率改善 |
| コスト削減 | 推論速度、サーバーコスト、オートスケーリング性能 |

---

## 3. KPI設定のステップと具体例

### ステップ①：ビジネスゴールの明確化

- 例：ECサイトの購入率を上げたい
- ゴール：レコメンドの最適化によるCVR向上

### ステップ②：中間指標と最終指標に分ける

| 中間KPI（モデル性能）| 最終KPI（ビジネス効果） |
|------------------|---------------------|
| Precision, Recall, F1 | 購入率、平均注文金額、解約率 |

### ステップ③：KGIとのつながりを意識する

- **KGI（Key Goal Indicator）**：最終的な成果目標（例：売上30%増）
- KPI：その達成に向けたモニタリング用指標

### ステップ④：SMARTに設定する

- **S（Specific）**：明確で具体的に
- **M（Measurable）**：測定可能
- **A（Achievable）**：実現可能
- **R（Relevant）**：ビジネスと関連性あり
- **T（Time-bound）**：期限つき

#### ✅ 例：ユーザー離脱予測モデルのKPI

| 分類 | 指標 | 値 |
|------|------|----|
| 中間KPI | AUC | 0.85以上 |
| 中間KPI | Recall（解約ユーザー）| 80%以上 |
| 最終KPI | 解約率 | 10%削減 |
| 最終KPI | サポートコスト | 月20万円削減 |

---

## 4. 機械学習プロジェクトの始め方：フェーズ別ガイド

### フェーズ1：ビジネスヒアリングとゴール設計

- 誰の、どんな課題を解決するのか？
- どの部署がKPIを持つのか？

### フェーズ2：データ理解と仮説立案

- どんなデータがあるか？
- どの変数が重要そうか？→EDA（探索的データ分析）

### フェーズ3：MVPモデルの構築と仮KPI評価

- 小規模でもいいので、まずモデルを作り、中間KPIで評価
- フィードバックをビジネス側と回す

### フェーズ4：本番化・スケーリング

- モデルを本番環境で運用
- 実データで**KPIがビジネスゴールと連動しているか**確認

---

## 5. よくある失敗とその回避策

| 失敗例 | 原因 | 解決策 |
|--------|------|--------|
| モデル精度は高いのに売上が伸びない | KPIが技術指標だけでビジネスにつながっていない | 最終KPI（売上など）を含める |
| 中間KPIが達成されても意思決定に使われていない | 評価指標が現場と乖離 | 現場にヒアリングして評価軸をすり合わせる |
| 目標が曖昧なまま始めた | KGI・KPIが未設定 | 初期にビジネスゴールとリンクしたKPIを設計する |

---

## 6. 成功事例とKPIの結びつき

### 🎯 成功例：小売チェーンの需要予測モデル

- **目的**：在庫の最適化による廃棄削減
- **中間KPI**：RMSE < 10%
- **最終KPI**：在庫ロス20%減少、利益率5%アップ

### 🎯 成功例：チャットボットの自動応答モデル

- **目的**：サポートコストの削減
- **中間KPI**：意図分類F1スコア > 0.92
- **最終KPI**：オペレータ対応件数30%削減

---

## 7. おわりに：KPIは「測る」だけでなく「導く」ためのもの

機械学習プロジェクトでは、精度やAUCといった指標に目が行きがちですが、本当に重要なのは**ビジネスへの価値を「見える化」すること**です。KPIは、プロジェクトの方向性を導き、関係者全体が同じゴールを目指すための羅針盤です。

---

## ✍️ まとめ

- KPIは「精度」だけでなく「ビジネスゴール」とリンクすべし
- 中間KPI（モデル性能）と最終KPI（ビジネス効果）を分ける
- プロジェクト初期からKGI・KPIを設計する
- フェーズごとにKPIを見直しながら柔軟に対応
- 成功の鍵は、**現場とKPIの整合性**

---

ご希望があれば、この内容を**Notionブログ記事形式、Markdown、PowerPoint資料、Qiita投稿向け記事**などに変換することもできます！お気軽にどうぞ。
【注意喚起】あなたのメールアドレスが狙われる！実在アドレスを偽装した「なりすましメール」の手口と対策方法

# 【注意喚起】あなたのメールアドレスが狙われる！実在アドレスを偽装した「なりすましメール」の手口と対策方法

近年、実在するメールアドレスを悪用した「なりすましメール」が増加しています。今回は筆者が運営するサービス『Disnana』のサポート用メールアドレス「support@disnana.com」を例に、実際に届いたなりすましメールを紹介し、その見分け方や対策方法を解説します。

## 実際に届いたなりすましメールの内容

以下は実際に筆者宛てに届いた詐欺メールの件名と原文（英文）とその日本語訳です。
※パスワードやビットコインウォレット情報は犯罪防止のため伏字処理しています。

### 【原文】
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4028223/10964b7c-c7dd-463a-932b-d0e44586842a.png)

### 【翻訳】
ご挨拶申し上げます！私は専門的なハッカーであり、あなたのオペレーティングシステムをハッキングしました。現在、私はあなたのアカウント（support@disnana.com、パスワード：＊＊＊）への完全なアクセス権を持っています。
また、過去数ヶ月間、あなたの行動を密かに監視していました。これは成人向け動画サイト訪問時にマルウェアが侵入したため可能となりました。
トロイの木馬ウイルスにより、私はあなたのコンピューターやその他デバイスへ無制限にアクセス可能です。
画面上の全てを見ることができ、カメラやマイクも自由に操作できます。
さらに個人情報やチャット履歴にも完全アクセス可能です。
私のマルウェアはドライバーベースであり、4時間ごとに署名を更新するためアンチウイルスソフトでは検出できません。
私はあなたが自慰行為をしている場面と、その時見ていた動画を並べたビデオを作成しました。
この動画をあなたの連絡先全員へ簡単に送信できます。
これを避けたいなら、50時間以内に1270米ドル相当のビットコインを私のウォレット（＊＊＊）へ送金してください。送金が確認され次第、この動画は削除し、私は完全に姿を消します。
このメッセージを他人と共有した場合は即座に動画を公開します。幸運を祈ります！

## 📌 このメールのおかしな点・突っ込みどころ

- **「ドライバーベースで4時間ごとに署名更新」？**  
  Windows Defenderなど一般的なアンチウイルスソフトはカーネルレベルで動作する不審なドライバーや頻繁な署名変更を簡単には見逃しません。むしろ4時間ごとの更新という主張自体が逆に怪しく、不自然です。

- **「開封通知でカウントダウン開始」？**  
  一般的なメールクライアントでは開封通知はユーザー側で許可しない限り送信されません。このような脅迫文句は技術的根拠がありません。

- **「成人向けサイト訪問で感染」？**  
  最近ではブラウザやOS自体が強固になっており、単なるサイト訪問だけで即座に完全支配されるケースは極めて稀です。

- **「数クリックで全連絡先へ動画送信」？**  
  仮にハッキングされたとしても、大量の連絡先へ一斉送信するには相応の準備が必要です。「数クリック」という表現は明らかに誇張されています。

- **「英文なのに不自然な表現」**  
  「passionate masturbation sessions」など、不自然かつ奇妙な言い回しが多く、ネイティブスピーカーから見ても違和感があります。


## なりすましメールが迷惑メールフォルダに入った理由

今回受信したメールはGmailによって自動的に迷惑メールフォルダへ分類されました。その理由は、送信元が適切な認証設定（SPF/DKIM/DMARC）を行っておらず、「softfail」と判定されたためです。

逆に言えば、正規のメールアドレス所有者が適切な認証設定を行っていれば、このような偽装メールは基本的に迷惑メールフォルダへ自動的に分類されることになります。


## 🔒 なりすまし被害から守るための対策方法

- **運営者側**: SPF/DKIM/DMARC設定
- **個人ユーザー側**: 二要素認証・パスワード管理・不審リンク非クリック・セキュリティソフト利用


## 📞 万一被害や不安がある場合は相談窓口へ

- 警察庁サイバー事案オンライン受付窓口  
- フィッシング対策協議会（info@antiphishing.jp）  
- IPA情報セキュリティ安心相談窓口（03-5978-7509）  


## ⚠️ 最後に：誰でも被害者になる可能性があります

今回紹介した内容は決して他人事ではありません。日頃からセキュリティ意識を高め、適切な対策で被害防止につとめましょう。

※本記事内で紹介した内容はあくまで一例であり、「support@disnana.com」自体が不正利用されたわけではありません。同様の手口には十分ご注意ください。
【Go】XOR暗号を使用した暗号化、復号化のサンプルコード


## 概要


[**暗号技術入門 第3版**](https://amzn.asia/d/4EzqngT)に出てきたXOR暗号で暗号化、復号化をGoで実装してみた


## サンプルコード


```go
package main

import (
	"crypto/rand"
	"encoding/hex"
	"fmt"
)

// XOR暗号化・復号化を行う関数
// data: 暗号化または復号化する平文または暗号文
// key: 使用する鍵
// XOR演算を適用し、暗号化または復号化した結果を返す
func xorEncryptDecrypt(data, key string) string {
	dataBytes := []byte(data)              // 平文または暗号文をバイト列に変換
	keyBytes := []byte(key)                // 鍵をバイト列に変換
	output := make([]byte, len(dataBytes)) // 出力用のバイト列を準備

	keyLength := len(keyBytes) // 鍵の長さを取得

	// XOR演算を各バイトに対して適用
	for i := 0; i < len(dataBytes); i++ {
		output[i] = dataBytes[i] ^ keyBytes[i%keyLength] // i番目のデータバイトと鍵バイトをXOR
	}

	// 結果を文字列として返す
	return string(output)
}

// 文字列をバイナリ形式の文字列に変換
func toBinaryString(data string) string {
	binaryStr := ""
	for _, c := range data {
		binaryStr += fmt.Sprintf("%08b ", c)
	}
	return binaryStr
}

// 平文と同じ長さの鍵を生成する関数
func generateRandomKey(length int) (string, error) {
	key := make([]byte, length)

	_, err := rand.Read(key)
	if err != nil {
		return "", err
	}

	return string(key), nil
}

func main() {
	plaintext := "HelloWorld"
	key, err := generateRandomKey(len(plaintext)) // 平文と同じ長さの鍵を生成
	if err != nil {
		fmt.Println("ランダム鍵の生成に失敗しました:", err)
		return
	}

	fmt.Printf("平文: %s\n", plaintext)
	fmt.Printf("暗号文: %s\n", hex.EncodeToString([]byte(encrypted)))

	// 復号化は暗号化と同じ操作を行う（XORは可逆操作）
	decrypted := xorEncryptDecrypt(encrypted, key)
	fmt.Printf("復号文: %s\n", decrypted)
}

// 出力
// 平文　: HelloWorld
// 暗号文: 294fd36b7622b728ab71
// 復号文: HelloWorld

```
Pythonプログラムで引数を受け取る方法(argparse)

```
# 実行例：Alice 25がひきす
python main.py Alice 25 --verbose
```
```py
import argparse

# ArgumentParser の作成
parser = argparse.ArgumentParser(description="引数を処理するスクリプト")

# 引数の定義
parser.add_argument("name", type=str, help="名前を入力してください")
parser.add_argument("age", type=int, help="年齢を入力してください")

# オプション引数（-- を付けるとオプションになる）
parser.add_argument("--verbose", action="store_true", help="詳細出力を有効にする")

# 引数を解析
args = parser.parse_args()

# 取得した引数を表示
print(f"名前: {args.name}")
print(f"年齢: {args.age}")

if args.verbose:
    print("詳細モードが有効です")
```
```
# ヘルプ呼び出し
python main.py --help

usage: main.py [-h] [--verbose] name age

引数を処理するスクリプト

positional arguments:
  name        名前を入力してください
  age         年齢を入力してください

options:
  -h, --help  show this help message and exit
  --verbose   詳細出力を有効にする
  
```
アクセスキー作成から90日経過したらメール通知する

# 前置き
AWSではアクセスキーは定期的にローテーションすることが推奨されています。
今回はアクセスキーが作成されてからメールで通知する方法を備忘として記載します。

# やり方①Amazon EventBridge+AWS Config+SNS
Amazon EventBridgeでイベントパターンパターンとして以下を定義
```
{
  "source": ["aws.config"],
  "detail-type": ["Config Rules Compliance Change"],
  "detail": {
    "configRuleName": ["access-keys-rotated"],
    "newEvaluationResult": {
      "complianceType": ["NON_COMPLIANT"]
    }
  }
}
```

ターゲットとしてSNSを選択。
この方法だとAWS Configのマネージドルール「access-keys-rotated」が非準拠になった際に以下のようなメールがくるが、すごく見づらい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4021557/6c20f308-a5a0-4428-9127-105f12040a87.png)

# やり方②　AWS User Nortificationsの通知機能を使う
イベントルールにAWS Configを選べる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4021557/4a051ef4-0544-4753-a5e2-b65a2e29a251.png)

フィルター条件で細かくカスタマイズすることも可能。
（下記では「準拠」⇒「非準拠」をトリガーとして設定）
```
{
  "detail": {
    "configRuleName": [
      "access-keys-rotated"
    ],
    "newEvaluationResult": {
      "complianceType": [
        "NON_COMPLIANT"
      ]
    },
    "oldEvaluationResult": {
      "complianceType": [
        "COMPLIANT"
      ]
    }
  }
}
```
OpenAI API経由で音声モデルを試す

試します。

https://openai.com/index/introducing-our-next-generation-audio-models/

前回はGPTでテキスト生成してからText to Speechを行っていましたが、一回のやり取りで音声が生成できるんですね。

https://qiita.com/taka_yayoi/items/f0fd89e2c93808423102

こちらのサンプルを動かします。

https://platform.openai.com/docs/guides/audio

```py
%pip install -U openai
%restart_python
```

```py
import os
os.environ['OPENAI_API_KEY'] = dbutils.secrets.get("demo-token-takaaki.yayoi", "openai_api_key")
```

```py
import base64
from openai import OpenAI

client = OpenAI()

completion = client.chat.completions.create(
    model="gpt-4o-audio-preview",
    modalities=["text", "audio"],
    audio={"voice": "alloy", "format": "wav"},
    messages=[
        {
            "role": "user",
            "content": "Is a golden retriever a good family dog?"
        }
    ]
)

print(completion.choices[0])

wav_bytes = base64.b64decode(completion.choices[0].message.audio.data)
with open("dog.wav", "wb") as f:
    f.write(wav_bytes)
```

再生します。

```py
from IPython.display import Audio
Audio("dog.wav")
```

:::note info
こちらには音声ファイルを貼り付けられないので以下の日本語の例をYoutubeにアップロードしています。
:::

日本語ではどうでしょうか。

```py
completion = client.chat.completions.create(
    model="gpt-4o-audio-preview",
    modalities=["text", "audio"],
    audio={"voice": "alloy", "format": "wav"},
    messages=[
        {
            "role": "user",
            "content": "ゴールデンレトリバーは良い家庭犬ですか？"
        }
    ]
)

print(completion.choices[0])

wav_bytes = base64.b64decode(completion.choices[0].message.audio.data)
with open("dog_japanese.wav", "wb") as f:
    f.write(wav_bytes)
```

```py
from IPython.display import Audio
Audio("dog_japanese.wav")
```

<iframe width="560" height="315" src="https://www.youtube.com/embed/1QxCk6XHmGk?si=haOK-YjrYlriGMTs" 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>

### はじめてのDatabricks

[はじめてのDatabricks](https://qiita.com/taka_yayoi/items/8dc72d083edb879a5e5d)

### Databricks無料トライアル

[Databricks無料トライアル](https://databricks.com/jp/try-databricks)
特定のゲームのオンラインモードなどを禁止する方法

Windowsです。

ゲームなどで、オンライン状態になりたくないことありますよね、mod開発の時とかbanされないようにするためにやりたかった利すると思います。

まず、コントロールパネルから
```
コントロール パネル\システムとセキュリティ\Windows Defender ファイアウォール
```
を開いて詳細設定を押します。

そしたら、新しい規則から、プログラムを押します。
禁止したいプログラムのパスを設定します。

そしたら、接続をブロックスするを押します。
これでかんｒｙ
フロントエンド入門：Google ChromeでローカルのHTMLファイルが開けないときの対処法（未実施）

## はじめに

:::note alert
**・補足：**
この記事で紹介している手順は、私自身はまだすべて実施していません。状況に応じて適切な方法を選んで試してみてください。
:::

Google ChromeでローカルのHTMLファイルを開こうとした際に「サイトが安全に接続できません」というエラーが表示されることがあります。

この問題は、Chromeのセキュリティ設定や拡張機能の影響によるものです。本記事では、その解決策を詳しく解説します。

## 書こうと思ったきっかけ
筆者自身がVS CodeのエクスプローラーからGoogle ChromeにHTMLファイルをドラッグ＆ドロップした際にこの問題に直面しました。

:::note info
**個人の備忘録程度の走り書きとなっておりますが、温かい目で見守っていただければ幸いです。**
:::

**同じように困っている方がいるのではと思い、対処方法をまとめました。**

## ローカルファイルのアクセスを許可する
Chromeはセキュリティ上の理由で、ローカルファイル (`file://`) のスクリプトやリソースの読み込みをブロックすることがあります。

***その場合、Chromeの起動オプションを変更することで解決できるかもしれません...（未実施）。***

### **解決策**
#### **Chromeを特別なフラグ付きで起動する**
1. Chromeを完全に閉じる。
2. ターミナルまたはコマンドプロンプトを開く。
3. 以下のコマンドを実行してChromeを起動する。

   **Windows の場合**
   ```sh
   chrome.exe --allow-file-access-from-files
   ```

   **Mac の場合**
   ```sh
   open -a "Google Chrome" --args --allow-file-access-from-files
   ```

   **Linux の場合**
   ```sh
   google-chrome --allow-file-access-from-files
   ```

4. この状態でHTMLファイルを再度Chromeにドラッグ＆ドロップし、動作を確認。

## Chrome の拡張機能が影響している場合
セキュリティ系の拡張機能（例: Adblock, Privacy Badger など）がローカルファイルの読み込みをブロックしている可能性があります。

### **解決策**
1. Chromeのアドレスバーに `chrome://extensions/` を入力。
2. すべての拡張機能を一時的に無効にして、再度試す。

## セキュリティ設定を一時的に無効化する
ローカルのHTMLファイルが `https://` で開こうとして失敗している場合、以下の手順で試してください。

### **解決策**
1. `chrome://flags/` にアクセス。
2. `Insecure origins treated as secure` の設定を検索。
3. `file://*` を追加して適用。
4. Chromeを再起動。

## ローカルサーバーを利用する（推奨）
Chromeのセキュリティ制限を回避するために、ローカルサーバーを立てて `http://localhost` から開くのが最も確実な方法です。

### **簡単な方法**
**VS Code の Live Server 拡張機能を使う**

1. **VS Code の拡張機能** で `Live Server` をインストール。
2. HTMLファイルを開き、**右クリック → "Open with Live Server"** を選択。

または、手動でPythonの簡易サーバーを起動することもできます。

**Python 3 の場合**
```sh
python -m http.server 8000
```
その後、ブラウザで `http://localhost:8000/` にアクセス。

## まとめ
- まずは **Chromeを `--allow-file-access-from-files` オプション付きで起動** してみる。
- それでもダメなら、 **Live Server や Pythonのローカルサーバーを使うのが確実** です。

以上の方法を試してみて、うまくいかなかったらエラーメッセージなど詳しく調査してみてください！