OmniAICreator/Qiita-1.07M huggingface dataset:
Laravelで50項目以上の検索条件を動的に扱う方法

# Laravelで50項目以上の検索条件を動的に扱う方法

- 「画面からめちゃくちゃいっぱい条件が飛んでくる」
- 「テーブルも1個じゃなくて、複数にまたがってる」
- 「でも現場ルールで全部コントローラに書いてって言われる…」
そんな要件、ありますよね。
そんなときに役立つ、**検索条件を定義的に書いて、動的SQLを組み立てる方法**を紹介します。



## この記事でやること

- 入力された検索条件だけでSQLを動的に組み立てたい
- 条件は**50項目以上**あっても対応したい
- 検索対象のカラムは**複数テーブルにまたがる**
- **全部コントローラに書く現場ルール**を守りたい



##  ポイントはこれだけ！

✔ 条件の「定義」と「処理」を分ける  
✔ 条件は配列で定義して `foreach` で回す  
✔ LIKEとか>=とかは定義に入れちゃう  
✔ JOIN使えば他テーブルもいける  
✔ 空欄の条件は無視してOK！



##  実装サンプル（全部コントローラ内）

```php
public function search(Request $request)
{
    $query = DB::table('users')
        ->join('profiles', 'users.id', '=', 'profiles.user_id');

    // 条件をまとめてここで定義
    $conditionsMap = [
        'name'        => ['column' => 'users.name', 'operator' => 'like'],
        'email'       => ['column' => 'users.email', 'operator' => 'like'],
        'age_min'     => ['column' => 'profiles.age', 'operator' => '>='],
        'age_max'     => ['column' => 'profiles.age', 'operator' => '<='],
        'phone'       => ['column' => 'profiles.phone', 'operator' => 'like'],
        'gender'      => ['column' => 'profiles.gender', 'operator' => '='],
        'status'      => ['column' => 'users.status', 'operator' => '='],
        'created_from'=> ['column' => 'users.created_at', 'operator' => '>='],
        'created_to'  => ['column' => 'users.created_at', 'operator' => '<='],
        // さらに40項目以上追加可能
    ];

    //  入力されてる条件だけで検索する
    foreach ($conditionsMap as $key => $rule) {
        $value = $request->input($key);

        if ($value === null || $value === '') continue;

        $operator = $rule['operator'];
        $column = $rule['column'];

        $query->where($column, $operator, $operator === 'like' ? "%{$value}%" : $value);
    }

    //  必要なカラムだけ取ってくる
    $results = $query->select('users.*', 'profiles.phone')->get();

    return view('search.results', compact('results'));
}
```
🤔 これの何が良いの？
✅ どの条件が何のカラムに対応してるかが一覧で見える

✅ 条件が1つ増えても「定義を1行追加」するだけ

✅ コントローラ内だけで完結！現場ルールも守れる！

✅ 50項目あっても検索条件部分はコンパクト！

✅ 空欄は無視するので、気軽に使える！


# まとめ
検索項目がめちゃくちゃ多い、テーブルも複数ある、でもコントローラ内に全部書けって言われる…。
そんな時は、この「条件を定義にまとめて、ループで処理するスタイル」が便利でした。

このパターン、ぜひ使ってみてください！
必要なデータはformの中に、編集画面の登録・更新の切り替えはformの中のDBから取得したデータで行う

springbootの開発をしていて、思ったことを書き留めておこう。

**データの持ち運びはformで行うこと**

何を言っているのかというと、DBから取得した値をresultなどの変数に入れて
```
model.addAttribute("result", result);
```
なんてしていると、画面で入力エラーなどが起こった場合に消えてしまい、そのたびに再取得する必要が出てくる。
当然、上記のようなことをしていると入力エラー時の処理を書くたびに意識しないといけないし、当然取得漏れなどから不具合につながりやすい。

formに入れておけば再取得の必要が無く、使いまわせる。

<br>

**登録・更新の切り替えは、DBから取得したformの中のデータで行う**

登録・更新を行う画面は編集画面として１つのhtmlで行うことが多いかと思うが、登録時と更新時で登録・更新ボタンの表示や処理を切り替える必要が出てくる。

springbootならthymeleafを使うことが多いと思うが、その時に上記のresultなどで判断していると、先述の入力エラー時等が起きた際に登録・更新の切り替えに難儀する。

そのためDBで取得した値をformに入れて、それを使うのが確実だろう。
フォントのダウンロードとインストール

Kosugi Maruフォントのインストール手順
1. ダウンロード

    URL: Google Fonts - Kosugi Maru
    手順:
        「Download family」をクリック
        Kosugi_Maru.zipを解凍
        KosugiMaru-Regular.ttfを取得

2. インストール
フォントビューアを使用

    前提: フォントビューアがない場合、インストールが必要
    インストール手順:
        ターミナルで実行:
        bash

        sudo apt update
        sudo apt install gnome-font-viewer

        .ttfをダブルクリック → 「インストール」をクリック

3. 確認

    方法: 設定 → フォントで「Kosugi Maru」を確認
    使用: アプリで選択可能
GPT-4oの画像生成機能でひぐまDukeを作った

# はじめに

[GPT-4oの画像生成機能がすごい](https://openai.com/index/introducing-4o-image-generation/)らしいので、[Javaユーザグループ北海道のひぐまDuke](https://github.com/java-do/HigumaDuke)を作れるかな？を試してみた。

結論として、コンセプトを伝えればサクッと作ってくれるので、今後は日本各地でJavaユーザグループ...JUGを作るときにとても便利ということが明らかとなった。

## ひぐまDukeとは

![duke_72dpi.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8064/087a7621-f095-443b-ad0d-4f689edd6b34.png)

ひぐまDukeは、Javaユーザグループ北海道（Java Do）のマスコットDukeである。
世界各地のJUGでは、JavaのマスコットキャラクターDukeをベースに、活動する地域の特色や文化を取り入れたDukeを作成することが少なくない。

JUGをやろう！と思った時にDukeから先に作る Duke駆動コミュニティ立ち上げ を行うと、~~後に引けなくなって~~おすすめである。

ひぐまDukeも、Java Doが発足してから10年、一緒に歩んできた愛着のあるキャラクターである。

## GPT-4o で ひぐまDuke できるかな？

本稿執筆時点（2025年3月27日）に、ChatGPT Proのスマホアプリからプロンプトを送信した。

### プロンプト1

```
Javaユーザーグループ北海道のマスコットキャラクターであるひぐまDukeの画像を生成して
```

**生成結果（縦横比を保ったまま25%圧縮）**

![Javaユーザーグループ北海道のマスコットキャラクターであるひぐまDukeの画像を生成して](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8064/1dbfcddd-5882-46d7-b2c7-74c48e10505c.png)

コワイ！

**Java Doスタッフの反応**

```
微かにDukeの面影が…
Java好きな人をおびき出して襲ってそうですね😖
```
```
そんなDukeを吸収したカービィみたいな。。
```

### プロンプト2

プロンプト1に立て続けて実行（原文ママ）

```
そうではなく、鮭を加えたヒグマに跨がったDukeです
```

**生成結果（縦横比を保ったまま25%圧縮）**

![そうではなく、鮭を加えたヒグマに跨がったDukeです](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8064/eabfc3cf-eb1c-434c-ab4b-a66672075a80.png)

えっすごい。

でもDukeにはそんな足が無かった様な...

### プロンプト3

プロンプト2に立て続けて実行（原文ママ）

```
Dukeの足の線だけを消して
他は絶対に加工してはいけません
```

なお、「他は絶対に加工してはいけません」をつけないと、クマの足が消えたり、Dukeの手指が消えたり、目のハイライトが消えたりなど「悪くはないのですが、違う案も出してくれますか？」みたいなことが起こり、20回ぐらいプロンプトをちまちま変えながら繰り返した結果、このプロンプトが安定した。

**生成結果（縦横比を保ったまま25%圧縮）**

![Dukeの足の線だけを消して 他は絶対に加工してはいけません](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8064/301448f2-fc56-4730-8b2c-d66c1b7731b7.png)

いいじゃん。かわいいじゃん。

**Java Doスタッフの反応**

![hanou.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8064/9c5a80fc-89d6-4998-b618-d4333c74124f.png)

もうDiscordのアイコンになってる...

### プロンプト4

そういやDukeって5本指だっけ...? と気がついてしまったので、プロンプト3に立て続けて実行（原文ママ）

```
Dukeの手の指は5本ではなく4本にして
他は絶対に加工してはいけません
```

![Dukeの手の指は5本ではなく4本にして 他は絶対に加工してはいけません](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8064/69652696-6d2d-42c8-8e69-ff4a040531fc.png)

🎉こんどこそ完成！🎉

## おわりに

GPT-4oの画像生成機能はすごく、Dukeに加えたい要素を記述してあげると、ご当地Dukeをすぐに作れる。

つまり、Javaユーザーグループをすぐに作れるので、まだJUGのない県のJavaユーザーの皆さんはぜひご当地Dukeを作ってJUGも作ってください。

ただし「あれ？Dukeって足あったっけ？」みたいなこともあるので、[Dukeについて熟知](https://wiki.openjdk.org/display/duke/Main)し採用に責任を持つことが重要です。

## 補足1

ここまでくると、プロンプト4に立て続いて

```
XXXみたいにして
```

と書くだけでいろんなひぐまDukeにできます。楽しい〜😆

![3set.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8064/f0ca74f8-a694-468c-bd3e-c69c2bb4316d.jpeg)

でもオリジナルひぐまDukeがやっぱり好きなので、GPTひぐまDukeは偶に登場、としようかなと思っています。

## 補足2

![スクリーンショット 2025-03-27 1.27.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8064/56afcc50-fdc4-4e5f-89a9-dbaeb09ea7b7.png)

きちんとブロックされてますね。
Linux Mint 22.1 Cinnamonにgeditをインストールする方法

手順

    ターミナルを開く  
        メニュー > ターミナル（またはCtrl + Alt + T）
    パッケージリストを更新  
    bash

    sudo apt update

    geditをインストール  
    bash

    sudo apt install gedit

    起動確認  
    bash

    gedit

注意点

    接続: インターネット接続が必要
    エラー時: sudo apt updateを再実行
IoT三菱電機冷蔵庫MR-WZ55K

我が家にやってきたIoT冷蔵庫がネットに繋がる！と書いていたので試してみた記録。

# インターネット接続
冷蔵庫をインターネットに接続されたWi-Fiに繋ぐ必要があります。
Wi-FiはもちろんEnterprise暗号化には対応していないので、Personalの暗号化方式のAPが必要です。
WPA3-Personalに対応するかは未検証です。(めんどかった)
冷蔵庫は2.4GHz Wi-Fi4 1x1の仕様のようです。
キッチンに置くのに2.4GHz..電子レンジを使っているときは使えなさそうですね！
24時間、インターネットとの接続が切れると、冷蔵庫の無線機能がオフになるらしいです。


# できること(三菱電機アプリMyMU経由)
表1に三菱電機アプリMyMUの各機能のスクリーンショットを示しています。
- 冷蔵庫の各庫内のモード変更
    - 弱中強
    - 製氷オンオフ高速
    - 野菜室謎LED点灯やチルド室など 付加価値機能のオンオフモード切替
- 気くばりナビ
    - 製氷用給水タンク残量低下通知
    - ドア空いてますよ通知
- エコ意識向上機能
    - ドア開け回数カウンタ

アプリには今流行りの?オートメーション機能があり、時間トリガー、端末の位置情報トリガー、機器のセンサーのしきい値トリガーで、指定したアクションを自動実行する機能がありましたが、冷蔵庫は非対応。

表1 三菱電機アプリスクショ
|冷蔵庫機能ホーム|野菜室画面|製氷室画面|エコ画面|通知履歴画面|オートメーション機能ホーム(冷蔵庫非対応)|
| --- | --- | --- | --- | --- | --- |
|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4035914/67be94af-5582-4701-8e40-8f52cf51738a.png)| ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4035914/6329bbd7-1d75-4edc-aead-66022cbef2a3.png)|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4035914/14284629-b816-4d17-9822-fea4421f842d.png)| ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4035914/2abb56c9-969d-4b28-a859-3a68bbfc52a6.png)  | ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4035914/4728190d-4aab-449d-8ecd-cacd2fc64ed3.png)  |![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4035914/7ce3dd6d-8207-49ce-b9e4-20011a02ed12.png)  |



# アプリでの設定変更の反映の流れ
次の2024年1月26日に公開された三菱電機の資料が見つかりました。ありがたい。

https://speakerdeck.com/yukiogawa/postmanwohuo-yong-sitajia-dian-apuripuratutohuomuapinoshi-yan-xiao-lu-hua?slide=7

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4035914/ac522a7d-83bd-4965-b53e-fa86fb4a12c7.png)

通信の流れは
三菱電機アプリ--(インターネット)->三菱電機のクラウドAWS--(インターネット)->冷蔵庫
のようです。
スマホからの通信をパケットキャプチャしたところ、アプリケーションの通信はTLC1.3で暗号化されており覗けない。


# 冷蔵庫仕様調査
- 同一LAN内からの通信-->ゲートウェイからの通信以外は応答しない
- ゲートウェイルータからnmapによる全ポートスキャンを実施 -->80番ポートのみOpen

# アプリ仕様調査
Not Yet


# 今後要調査事項
- 操作用APIの仕様、URL
    - 冷蔵庫本体に直接操作
    - 三菱電機クラウドへのリクエストURL(アプリ調査 規約を事前に要確認)



# 今後やってみたいこと
- 深夜帯は冷蔵庫を弱モードに
- Home Assistantで設定を管理
Azure OpenAIとPythonでレジュメ要約AIを作ってみた

## はじめに

最近、ChatGPTや生成AIが話題ですが、Azure OpenAIを使えば企業向けにも安全に大規模言語モデル（LLM）を活用できます。本記事では、Azure OpenAIのAPIをPythonから使って、履歴書（レジュメ）を100語以内で要約する簡単なアプリケーションを作成してみます。

---

## 使う技術
- Azure OpenAI Service（GPT-3.5 Turbo）
- Azure AD 認証
- Python
- Pandas

---

## ステップ 1: 環境構築

```bash
pip install openai azure-identity pandas
```

Azure Portalで下記を漏れなく取得:
- Azure OpenAI Endpoint
- Deployment Name
- Tenant ID
- Client ID / Secret

※Qiitaの記事上ではこれらの情報を公開しないよう注意しましょう。`os.environ.get()` などで環境変数から読み込むのがポイントです。

---

## ステップ 2: Azure OpenAIの設定

```python
from azure.identity import ClientSecretCredential, get_bearer_token_provider
from openai import AzureOpenAI
import os

credential = ClientSecretCredential(
    tenant_id=os.environ.get('AZURE_TENANT_ID'),
    client_id=os.environ.get('AZURE_CLIENT_ID'),
    client_secret=os.environ.get('AZURE_CLIENT_SECRET')
)

scopes = "https://cognitiveservices.azure.com/.default"
azure_ad_token_provider = get_bearer_token_provider(credential, scopes)

client = AzureOpenAI(
    azure_endpoint=os.environ.get('AZURE_OPENAI_ENDPOINT'),
    api_version="2024-02-15-preview",
    azure_ad_token_provider=azure_ad_token_provider
)
```

---

## ステップ 3: CSVからレジュメデータ読み込み

```python
import pandas as pd

url = "https://raw.githubusercontent.com/CloudPak-Outcomes/Outcomes-Projects/main/watsonx-governance-l4/data/resume_summarization_test_data.csv"
df = pd.read_csv(url)
df.head()
```

---

## ステップ 4: GPTで要約作成

```python
PROMPT_TEMPLATE = """
You will be given a resume. Please summarize the resume in 100 words or less.

--- start of text ---
{text}
--- end of text ---
""".strip()

summaries = []
for index, row in df.iterrows():
    resume = row[0]  # 実際のレジュメ文章
    response = client.chat.completions.create(
        model=os.environ.get('AZURE_OPENAI_DEPLOYMENT_NAME'),
        messages=[{"role": "user", "content": PROMPT_TEMPLATE.format(text=resume)}],
        max_tokens=200
    )
    summary = response.choices[0].message.content
    print(f"{index}: {summary}")
    summaries.append(summary)

df['generated_text'] = summaries
```

---

## ステップ 5: 結果を表示

```python
df[['generated_text']].head()
```

必要に応じてCSV出力も可能です:

```python
df.to_csv("resume_with_summary.csv", index=False)
```

---

## おわりに

Azure OpenAIを利用すれば、安全に企業用LLMを活用して、レジュメのような自然言語データを短文で要約するサービスが作れます。

今後は一次分析や、職種ポジションとのマッチングへの応用も検討できますね。

ご覧いただきありがとうございました！
Linux Mint 22.1 Cinnamon タスクバー（パネル）を小さくする

Linux Mint 22.1 Cinnamon タスクバー（パネル）を小さくする
手順

    パネルを右クリック
        右クリック > "パネルの編集モード" をオン
    高さ調整
        ドラッグ または パネルの設定 > 高さスライダー で小さく
    アイコンサイズ（任意）
        パネルの設定 > "シンボリックアイコン" オン  
        カスタムサイズ で調整
    終了
        右クリック > "パネルの編集モード" をオフ

注意

    制限: 高さには下限あり、見づらくなる可能性
    自動隠し: パネルの設定 > "自動的に隠す" で省スペース

これで簡単にタスクバーを小さくできます！
Google ChromeからSafariにiCloudを使用せずブックマークを移行する

# はじめに

Google Chromeで登録したブックマークをiOSのSafariに移行する場合、iCloud for Windowsをインストールして同期させる方法がよく使われますが、今回はiCloud for Windowsを使用せず、iOS 18.2以降で利用可能となった別のブラウザのデータをSafariに読み込む機能を使用した方法でブックマークを移行してみます。

# 環境

- Windows 11 + Google Chrome
- iOS 18.3.2 (18.2以降が必要) + Safari

# 手順

おおまかな手順は次の通りです。

1. Google Chromeからブックマークをエクスポートする
1. エクスポートしたファイルをiPhoneに転送する
1. iPhoneでブックマークをインポートする

## Google Chromeからブックマークをエクスポートする

Google Chromeヘルプに記載されている手順にしたがって、ブックマークをエクスポートします。

https://support.google.com/chrome/answer/96816?hl=ja

1. Google Chromeを起動し、右上の [︙] アイコン > [ブックマークとリスト] > [ブックマーク マネージャ] を選択します。
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348651/7fcec356-38e4-4979-873d-3ec2ac822f33.png)

1. 上部の [︙] アイコン > [ブックマークをエクスポート] を選択します。
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348651/78e127b2-0211-410c-8056-ea83bfd3bba0.png)

1. 任意の場所にファイルを保存します。

ここまでで、Google ChromeのブックマークがHTMLファイルとして書き出されます。

## エクスポートしたファイルをiPhoneに転送する

上記で書き出されたHTMLファイルを、クラウドストレージやメール等の任意の手段でiPhoneに転送します。
転送の具体的な方法についてはここでは割愛します。

なお、後続の手順でファイルアプリの機能を介してファイルを選択するため、ファイルアプリから参照可能な場所にこのファイルが保存されている必要があります。

### 例：メールにファイルを添付して転送する場合

メールでファイルを添付して転送する場合は、受信したメールの添付ファイルをファイルアプリへ保存する必要があります。

https://support.apple.com/ja-jp/guide/iphone/iph7fe7a50a7/ios

## iPhoneでブックマークをインポートする

こちらも、iPhoneユーザガイドに記載されている手順にしたがって、ブックマークをインポートします。

https://support.apple.com/ja-jp/guide/iphone/iph63846804e/ios

1. 設定アプリを開き、[アプリ] > [Safari] を選択します。
1. [履歴とWebサイトデータ] セクションにある [読み込む] をタップします。
![IMG_7413.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348651/99a58e7f-686a-4f0a-9b59-454e90f4e341.jpeg)
1. [ファイルを選択…] をタップします。
![IMG_7407.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348651/a3cd8e88-1053-4bcb-9f7d-d902d90763f3.jpeg)
1. iPhoneに転送したHTMLファイルを選択します。
![IMG_7408.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348651/e7465396-677f-40c0-bc53-b35ac0d6a853.jpeg)
1. 読み込んだデータの説明が表示されます。問題なければ [Safariに読み込む] をタップします。
![IMG_7410.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348651/3014f97c-3dd5-40fa-9cdf-640d4e2d7ff8.jpeg)
1. 「読み込みに成功しました」と表示されたら [完了] をタップします。
![IMG_7411.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348651/1e65dc9f-9f0d-48c7-819e-9fed4b3d2486.jpeg)
1. 読み込んだファイルを削除するか確認されるので、ファイルが不要であれば ["ファイル名" を削除] をタップします。
![IMG_7414.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348651/1601ec9f-5bc9-4c9d-a448-57e9a19c24c1.jpeg)

### インポート後のブックマーク整理

インポートされたブックマークは、「読み込み済み (YYYY/MM/DD)」フォルダに登録されます。

![IMG_7412.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348651/1c20dc64-ad31-4abd-ad37-2760ab073594.jpeg)

必要に応じて、フォルダ内のブックマークを別の場所に移動させます。
具体的な手順は、iPhoneユーザガイドを参照してください。

https://support.apple.com/ja-jp/guide/iphone/iph42ab2f3a7/ios

# 補足

iPadOS 18.2以降でも、iOSと同様に別のブラウザのデータをSafariに読み込ませることが可能のようです。

https://support.apple.com/ja-jp/guide/ipad/ipadb9c87d5c/ipados
Hydration failed とエラーが出たらちょっと踏みとどまってほしい

# はじめに

Suspense を使って遊んでるときに新しい気付きがあったので、備忘録として残します。いまのところの理解としてはフィールドのアクセスは :ok: メソッド呼び出しは :ng: です。

## 環境

- react-router v7.3
- react v19

# 出会いは突然に

Suspense を使ってローディングを表示して、表示したい内容のフェッチが終わって無事に表示できたと思いきや、Chrome Developer Tools の console に次のようなメッセージがありました。

```
Uncaught Error: Hydration failed because the server rendered HTML didn't match the client. As a result this tree will be regenerated on the client. This can happen if a SSR-ed Client Component used:

- A server/client branch `if (typeof window !== 'undefined')`.
- Variable input such as `Date.now()` or `Math.random()` which changes each time it's called.
- Date formatting in a user's locale which doesn't match the server.
- External changing data without sending a snapshot of it along with the HTML.
- Invalid HTML tag nesting.

It can also happen if the client has a browser extension installed which messes with the HTML before React loaded.

https://react.dev/link/hydration-mismatch
```

詳細はわかっていませんが、どうやらサーバーサイドでレンダリングした結果とクライアントでレンダリングした結果に違いがあるときに起きるエラーのようです :thinking: ただ、Suspense を使ってるだけなのに不思議でした。

# 原因

Qiita API から記事を取得して `Article` クラスのインスタンスを作成して一覧を表示していたのですが、コンポーネントから getter format_created_at を呼び出していました。

```react
<div>
{ article.format_created_at }
</div>
```

```typescript filename:Article.ts
export class Article {
  public created_at: string

  constructor(
    created_at: string
  ) {
    this.created_at = created_at
  }

  get format_created_at(): string {
    const date = new Date(created_at);

    const year = date.getFullYear();
    const month = String(date.getMonth() + 1).padStart(2, '0');
    const day = String(date.getDate()).padStart(2, '0');

    return `${year}-${month}-${day}`
  }
}
```

どういう原因で Hydration failed となるかわかっていませんが、メソッド呼び出しをすると起きるようです :thinking: ただ、フィールドでアクセスするとエラーなく表示することができます。
Linux Mint 22.1 CinnamonでMozcをインストールする方法

#Linux Mint 22.1 CinnamonでMozcをインストールする方法

手順

    必要なパッケージをインストール
        fcitx5（入力メソッドフレームワーク）とfcitx5-mozc（Mozc本体）をインストールします。  
        
    bash

    sudo apt update
    sudo apt install fcitx5 fcitx5-mozc

    入力メソッドをFcitx5に設定
        Fcitx5をデフォルトの入力メソッドとして設定します。
        
    bash

    im-config -n fcitx5

    Fcitx5の設定を開く
        メニューから「Fcitx 5 Configuration」を検索して起動するか、ターミナルで以下を実行します。
    bash

    fcitx5-configtool

    Mozcを入力メソッドとして追加
        「入力」タブで「+」ボタンをクリック。
        リストから「Mozc」を選択し、「OK」を押す。
        「English (US)」と「Mozc」がリストに表示されるようにする。
        
    ショートカットを設定（任意）
        半角/全角で切り替え可能。必要に応じて「Global Options」から変更。
        
    システムを再起動
        設定を適用するため、再起動します。
        
    bash

    reboot

    日本語入力を確認
        再起動後、システムトレイにFcitxアイコンが表示されるはず。「Mozc」を選択し、日本語入力をテスト。

注意点

    Cinnamonでの表示: システムトレイにFcitxアイコンが表示されない場合、設定を確認し再起動を試す。
    
    IBusとの競合: IBusが有効だと競合する可能性あり。不要なら削除（sudo apt remove ibus）。

※AIでファクトチェックして実機で試しました
問い合フォーム自動入力 / 送信

<br>
<h3>解説</h3>

```ruby: ✅ 
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.firefox.options import Options
from selenium.webdriver.firefox.service import Service

options = Options()
options.headless = False  # GUIモードで開く（headless=TrueにするとGUIなしで動作）

geckodriver_path = '/usr/local/bin/geckodriver'
service = Service(geckodriver_path)
driver = webdriver.Firefox(service=service, options=options)

driver.get("https://www.nipponcoating.co.jp/recruit_entry/")

# 名前要素 取得 (name属性を使って)
name_element = driver.find_element(By.NAME, "お名前")  # name属性が"名前"のフィールド

# '公開レポート'aタグ取得 
# driver.find_element(By.xpath("//a[@title='公開レポート']"))


# "岸田理沙"を名前フィールドに入力
name_element = driver.find_element(By.NAME, "お名前")
name_element.send_keys("ホゲ丸尾")


# 必要に応じて送信ボタンを押す場合
 submit_button = driver.find_element(By.NAME, "submit") 
 # 送信ボタンのname属性が"submit"の場合
 submit_button.click()


# 操作が完了したらブラウザを閉じる (必要に応じて)
# driver.quit()
```
バックエンドのディレクトリ構成について


# この記事について

バックエンドを勉強の備忘録です。
バックエンドのディレクトリでよく出てくるディレクトリ名についてまとめてみました。

## Controller（コントローラー）

役割: Model と View を仲介し、アプリケーションのフロー制御を担当

- ユーザーからのリクエストを受け取る
- 適切な Service を呼び出す
- 処理結果を View に渡す
- HTTP リクエストのルーティングとレスポンス生成

## Service（サービス）

役割: ビジネスロジックの実装とドメインルールの適用

- 複数のリポジトリを調整して、複雑なビジネスロジックを実装
- トランザクション管理
- ドメインロジックの実装
- コントローラーとリポジトリの間の仲介

## Repository（リポジトリ）

役割: データの永続化層とのやり取りを抽象化

- データアクセスロジックをカプセル化
- データベースや API などとのやり取りを担当
- ドメインオブジェクトと永続化層の変換
- SQL クエリの実行や ORM の利用

## Model（モデル）

役割: データとビジネスロジックを表現する

- データの構造と属性を定義する
- データの検証ルールを含む
- アプリケーションのビジネスルールを表現する

# 各コンポーネントの関係性

上記に加えてクライアントサイド( View )も含めるとアプリケーションのデータフローは通常次のようになります

1. User → View: ユーザーが UI で操作
1. View → Controller: リクエストがコントローラーに送信される
1. Controller → Service: コントローラーがサービスを呼び出す
1. Service → Repository: サービスがリポジトリを使用してデータ操作
1. Repository → データベース: リポジトリがデータベースと通信
1. Repository → Service → Controller → View → User: 結果が逆順に返される

# まとめ: 各層の責任範囲

View も含めると以下のようになります。

- View: ユーザーインターフェースとデータ表示
- Controller: リクエスト処理とフロー制御
- Service: 複雑なビジネスロジックの実装
- Repository: データアクセスの抽象化
- Model: データ構造とドメインルール

  以上を分離することにより、テスト容易性、保守性、再利用性が向上し、関心の分離（Separation of Concerns）が実現できます！
Codewars 7 kyu Anagram Detection

# Codewars 7 kyu Anagram Detection
https://www.codewars.com/kata/529eef7a9194e0cbc1000255/train/python
# Task
Complete the function to return true if the two arguments given are anagrams of each other; return false otherwise.

# Verbalization
Make all capital letter to small letter
Change alphabetical order
If equal the result of 2. Return true, if not return false.
 
# Code 
```py
# write the function is_anagram
def is_anagram(test, original):
    test = sorted(test.lower())
    original = sorted(original.lower())
    if test == original:
        return True
    else:
        return False

```
身体性をまとう人工知能 (3)

> 身体を持つAIが投げかける倫理的・哲学的問題を整理していきましょう。
>
> 日本で有名なSF映画、SF TVシリーズなどで出てくる身体を有する24個それぞれの人工知能システムについて次の順で考えることはできますか。
>
> - それぞれの人工知能システムについて
>   - 映画の中の人工知能システムを **思い出そう** 。
>   - その人工知能システムの **機能と象徴性** 。
>   - 投げかける **倫理的、哲学的問題** と解説。
>
> そして各分類を参考に、現実の社会への教訓を想像してください。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38013/a0349730-145a-4fb5-a975-f1036b2f1d55.png" width="360" />

Fig. GPT-4oで生成した画像「 **首の後ろの回路からケーブルが出ていて、電気回路のデバッグ** 」

---

以下のレポートでは、「身体を持つAIが投げかける倫理的・哲学的問題」を軸に、24のSF作品に登場する人工知能（以下AIやアンドロイド、ロボットと総称）の事例を掘り下げます。各作品については、（1）作品やキャラクターを思い出すための象徴的シーン、（2）AIの機能と象徴性、（3）そこから浮き彫りになる倫理的・哲学的問題、（4）問題の解説という流れで整理します。

その後、全作品にわたる「身体を持つAI」という観点での分類を試み、最終的に「現実社会への教訓」へと論を展開していきます。

【目次】
1. **はじめに：身体を持つAIという焦点**
2. **各作品のAIと投げかける問題**
	1.	スター・ウォーズ：C-3PO / R2-D2
	2.	スタートレック：データ少佐
	3.	『A.I.』：デイビッド
	4.	『ターミネーター』：T-800 / スカイネット
	5.	『ドラえもん』：ドラえもん
	7.	『エクス・マキナ』：エヴァ
	6.	『マトリックス』：アーキテクト
	8.	『鉄腕アトム』：アトム
	10.	『ウルトラセブン』シリーズ：第四惑星のロボット長官
	11.	『がんばれ!!ロボコン』：ロボコン
	17.	『ベイマックス』：ベイマックス
	18.	『アイアン・ジャイアント』：アイアン・ジャイアント
	20.	『マクロス』シリーズ：ゼントラーディ用AI兵器
	21.	『人造人間キカイダー』：キカイダー（ジロー）
3. **身体を持つAIの分類**
4. **現実社会への教訓**

----


**1. はじめに：身体を持つAIという焦点**

現代社会では、音声認識や画像認識、対話型AIが身近な存在となってきました。しかしSF作品に登場するAIは、さらに一歩進んだ「**身体を持つAI**」として描かれている場合が多々あります。身体を持つということは、単なる情報処理装置としての役割に加え、「**自分自身で行動し、感情らしきものを表現し、人間社会に介入する**」可能性をもたらします。

本レポートでは、24のSF作品から身体を有するAIキャラクターを取り上げ、物語内で示される**象徴的シーン**や**倫理的・哲学的問題**を抽出します。具体的には以下のような問いを意識しながら進めていきます。

- 「人間らしさ」とは何か？
- AIはどこまで人権あるいは道徳的配慮を受けるべきか？
- AIが自律行動をとるとき、責任は誰がどのように負うのか？
- AIと人間が共存する社会は可能なのか？

これらの問いを念頭に置きつつ、次章より作品ごとに見ていきます。


([前の記事 (SFでのAIのリスト)](https://qiita.com/shinya_ohtani/items/54cc380bf348ddf75fc6)) <- -> ([次の記事 (スター・ウォーズなど)](https://qiita.com/shinya_ohtani/items/298a163f345802258cbc))
Flutter/Bloc/Firestoreを用いた開発プロセス

# はじめに
私がアプリを個人開発する中で、どのようなプロセスで開発を進めているか備忘録的な意味を込めて残しておこうと思います。

# 開発環境
言語：Dart
フレームワーク：Flutter
アーキテクチャ：Bloc
DB：Firestore

# ディレクトリ構成
下記はlib配下のディレクトリ構成です。
主要なディレクトリを抜き出しています。
```
.
├── blocs
│   ├── hoge_bloc.dart
├── main.dart
├── models
│   ├── hoge_model.dart
├── repositories
│   ├── hoge_repository.dart
└── screens
    └── hoge_screen.dart
```

# 開発プロセス
1: DB設計を行う
まずはDBにどのようなデータを保存するか設計します。
イメージしたDBを元にFirestoreにコレクションとドキュメントのダミーデータを入れておきます。

2: modelの作成
設計を元にmodelを作成します。

``` hoge_model.dart
class HogeModel {
  HogeModel({
    required this.fuga,
  });
  
  final int fuga;

  factory HogeModel.fromDocument(DocumentSnapshot<Object?> doc) {
    final Map<String, dynamic> data = doc.data() as Map<String, dynamic>;
    return HogeModel(
      fuga: data['fuga'],
    );
  }

  Map<String, dynamic> toMap() {
    return <String, dynamic>{
      'fuga': fuga,
    };
  }
}
```

3: repositoryの作成
firestore↔BlocをつなぐためのAPIを作成します。
API作成時点でfirestoreとの接続確認を行っておくと良いと思います。

``` hoge_repository.dart
class HogeRepository {
  final FirebaseFirestore _firestore = FirebaseFirestore.instance;

  Future<void> addFuga(String fuga) async {
    await _firestore.collection('fugaCollection').add(fuga.toMap());
  }

  Future<String?> fetchFuga() async {
    final fugaDoc = await _firestore.collection('fugaCollection').doc('fugaDoc').get();
    if (fugaDoc.exists) {
      return HogeModel.fromDocument(fugaDoc);
    }
    return null;
  }
}
```

4: blocの作成
Bloc↔screenをつなぐためのBlocを作成します。

``` hoge_bloc.dart
class HogeBloc extends Bloc<HogeEvent, HogeState> {
  HogeBloc() : super(HogeState()) {
    on<HogeEventFuga>((
      HogeEventFuga event,
      Emitter<HogeState> emit,
    ) async {
      _hogeRepository.addFuga(
        event.fuga,
      );
    });
  }

  final HogeRepository _hogeRepository = HogeRepository();
}
```

5: screenの作成
画面を作成します。
``` hoge_screen.dart
class HogePage extends StatelessWidget {
  const HogePage({super.key});

  @override
  Widget build(BuildContext context) {
    return BlocProvider<HogeBloc>(
      create: (BuildContext context) => HogeBloc(),
      child: const HogeScreen(),
    );
  }
}

class HogeScreen extends StatelessWidget {
  const HogeScreen({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(
          'Hoge Screen',
        ),
      ),
      body: BlocBuilder<HogeBloc, HogeState>(
        builder: (BuildContext context, HogeState state) {
          return TextButton(
            child: const Text('button'),
            onPressed: () {
              context
                  .read<HogeBloc>()
                  .add(HogeEventFuga('piyo'));
            },
          );
        },
      ),
    );  
  }
}
``` 

# 最後に
私が紹介したのはデータの依存関係にしたがって依存元から実装していくやり方です。
逆にUIから実装していくのもありだと思います。
参考になる部分があれば幸いです。
Python code task

# Task
How many different ways are there to use 16 possible variables? Give the Python code.


# Verbalization
Calculation formula is 18C0 + 18C1 +18C2 …… + 18C18
nCr = n!/((n-r)!*r!) (use from math import factorial factorial(i) = i!)
Use roop and += (for i in range(18+1))
 
# Code 
```py
from math import factorial

#test n=18C0 
n= factorial(18)/factorial(18-0)*factorial(0)
n  


#test How many different ways are there to use 3 possible adjustment variables?
n =factorial(3)/(factorial(3-0)*factorial(0)) +factorial(3)/(factorial(3-1)*factorial(1)) +factorial(3)/(factorial(3-2)*factorial(2)) +factorial(3)/(factorial(3-3)*factorial(3))
n

h = 16
n = 0
for i in range(0,h+1):
    f = factorial(h)/(factorial(h-i)*factorial(i))    
    n += f
n

```

# Reference
https://www.geeksforgeeks.org/python-program-to-print-pascals-triangle/
Xcode インスト Venture 13.4.7

<h3> 結論 </h3>
<ul>
<li>コマンドからインストしたら、何回やってもダメ</li>
<li>App 公式storeからのインストじゃないとうまく行かない</li>
</ul>


<br>
<h3>これにアクセス ↓ </h3>

https://developer.apple.com/download/all/

これget!↓(Venture 13.7.4対応 Xcodeはこのversionのみ)
![スクリーンショット 2025-03-01 2.02.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628823/76fcec6c-7c79-4bfd-9838-5d8d932dd295.png)

<br>
<h3>コマンドからのインストの時、でるエラー画面 </h3>

![スクリーンショット 2025-02-28 14.50.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628823/a10b84b0-2e4c-43db-92da-30f62dc19509.png)




<br>
<h3>おまけ すでにインストされてんよ！画面 </h3>

![スクリーンショット 2025-02-28 14.19.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628823/f3d3a4be-923d-419d-bfbc-c6c8659da3eb.png)
GTC2025 現地参加レポート（Keynote、Exhibition編）

# GTC参加レポート：Keynote、Exhibition編

ここでは、GTCの目玉ともいえる **Keynote（基調講演）** と、技術と熱気が交差する **Exhibition（展示会場）** についてまとめていきます。

---

## 🎤 Keynote 体験記：ジェンスン・フアン降臨の瞬間

Keynote だけは、通常の会場である San Jose McEnery Convention Center ではなく、**SAP Center at San Jose** に場所を移して行われました。  
そう、あの **ジェンスン・フアン（Jensen Huang）** が登壇するからです！

![IMG_8667.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2561874/a9e977e8-c451-4780-93a2-f850b336bdd4.jpeg)

### 🚨 厳戒態勢の中での開催
- 水の持ち込みは禁止
- 金属探知ゲートを通過するセキュリティチェックあり

開始時間は 10:00 でしたが、  
「1時間前に行っても入れないかも？」という噂を聞き、**8:30に現地入り**。  
最初は長蛇の列に並んでいたのですが、**入口によって待ち時間が違う**ことに途中で気づき、列の少ない方へ移動したところ、意外とすんなり入場できました。

### 🪑 会場内の雰囲気と心の声
- 会場に入った後は、座席の最上部へ
- **満席の中、一度座るとほぼ身動きが取れない**
- 2時間の講演中「トイレに行きたくなったら？」「気分が悪くなったら？」という不安も…

もらった **水や果物にも手をつけられず**、身動きできないプレッシャーの中での講演鑑賞でした。

![IMG_8668.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2561874/b5eb519d-a829-43a0-880f-346e7f07313f.jpeg)

### 📸 現地だからこそ撮れた“ジェンスン豆粒ショット”
- 小さなジェンスン・フアン
- 小さなロボット
- 画面の文字も読めない

でも、**満員の会場の一体感と熱気**は現地ならでは。  
特に、**Disney Research × NVIDIA × Google DeepMind** の紹介で登場したロボットがとてもかわいらしく印象的でした。

![IMG_8680.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2561874/ce0f7755-af99-4f74-bc21-2bd04550c9ee.jpeg)

![IMG_8699.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2561874/9a646ca6-3c66-4b85-a8bf-fffaa502ea12.jpeg)


---

## 🏢 Exhibition hall：展示の多様性とスワッグ事情

展示会場では、もちろん **NVIDIA** が最大のブースを展開。  
加えて、以下のような **おなじみの大手ベンダー＋アジア系企業の強さ**が目立ちました。

### 💼 主な出展企業（一部）
- AWS  
- Microsoft Azure  
- Google Cloud  
- Oracle  
- IBM  
- Dell Technologies  
- 中国・台湾系の企業（多数）

説明員を見て「日本語いけるかな？」と思っても、**ほとんどが中国系のお名前**。  
この領域では **中国・台湾メーカーの存在感が圧倒的** だと再認識しました。

日本企業の出展も数社ありましたが、**大型ブースはなし**。ちょっと寂しい印象でした。

![IMG_8707.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2561874/e42ca2c7-6998-45ae-810f-45edad2c1f28.jpeg)

![IMG_8709.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2561874/232604c2-4153-4e9c-a38c-58f97166e993.jpeg)

---

## 🎁 スワッグは控えめ？
展示会では、**スワッグ（ノベルティグッズ）**を配っている企業が少なく、  
**re:Invent（AWS）に比べると物足りなさ**を感じました。

- 会期中にもらえたのは **Dell Technologies のみ**
- 積極的に集めようとはしなかったが、「欲しい」と思えるものも少なかった印象

---

## ✍️ まとめ

Keynoteは予想以上に過酷で、Exhibitionは多様性に富んでいました。  
ジェンスンの豆粒写真しか撮れなかったけど、**GTCの熱気はしっかり体感できました！**  
展示企業の傾向からも、**AIや半導体の主戦場がアジアにも広がっている**ことがよく分かりました。

---
六角格子の頂点座標

こんにちは。
六角格子の頂点座標を求めました。

図示例：
![https___qiita-image-store.s3.ap-northeast-1.amazonaws.com_0_54617_30599856-d2fd-490d-84e1-23851f7df9bb.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54617/f91e2bc2-0283-4267-b6e0-00c9d7158b5c.jpeg)

### source code
```hexagonal_lattice.py
#!/usr/bin/env python3
import math, sys
n = 2 if len(sys.argv) == 1 else int(sys.argv[1])

L = math.sqrt(3)/2
# [(1,0), (1/2, L)] # triangular-latice basis

vertices = []
for i in range(-n, n+1):
  for j in range(-n, n+1):
    k, l = i%3, j%2
    if k == 0 or k + l == 2:  # hexagonal vertices
      m = i + l/2
      vertices.append([m, j * L])

import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(9, 9))
ax.scatter(*tuple(zip(*vertices)))  # transpose
ax.set_aspect('equal')
plt.show()
```

#### 変種
また、```(i,j)```ループの部分をいろいろ変えても六角格子を得られます：

```python
for i in range(-n, n+1):
  for j in range(-n, n+1):
    if i%3 + j%3 != 2:  # hexagonal vertices
      m = i - l/2
      vertices.append([m, j * L])
```

他にも、
```python
for i in range(-n, n+1):
  for j in range(-n, n+1):
    m = (i * 3 - (i+j)%2) / 2
    vertices.append([m, j * L])
```
AIアルゴリズムトレードにおけるリスク管理：ケリー基準によるポジションサイズの最適化



## はじめに

AI（人工知能）を活用したアルゴリズムトレードは、人間の感情を排し、データに基づいた高速かつ高頻度な取引を可能にすることから、多くのトレーダーや投資家の注目を集めています。しかし、その高度な技術の裏側には、依然として市場の不確実性というリスクが存在します。AIトレードで長期的に成功を収めるためには、洗練されたアルゴリズムだけでなく、堅牢なリスク管理戦略が不可欠です。

この記事では、リスク管理の中でも特に重要なポジションサイジングと、その代表的な手法であるケリー基準について解説します。

## リスク管理とポジションサイジングの重要性

リスク管理とは、単に損失を避けることだけではありません。許容できるリスクの範囲内で、いかにしてリターンを最大化するかを考えるプロセスです。AIアルゴリズムトレードにおいては、個々のトレードの勝敗だけでなく、ポートフォリオ全体のリスクをコントロールすることが求められます。

その具体的な手法の一つがポジションサイジングです。これは、1回のトレードにどれだけの資金を投じるかを決定するプロセスを指します。適切なポジションサイジングを行わなければ、たとえ勝率の高い優れたアルゴリズムであっても、数回の大きな損失で資金を失ってしまう可能性があります。逆に、ポジションサイズが小さすぎると、十分なリターンを得ることができません。

## ケリー基準とは？

ケリー基準 (Kelly Criterion) は、長期的な資産成長率を最大化するための最適な投資比率（ポジションサイズ）を数学的に導き出す公式です。1956年にベル研究所の科学者ジョン・ケリー・ジュニアによって考案され、元々は通信理論に関する研究でしたが、ギャンブルや投資の世界で広く応用されるようになりました。

ケリー基準の目的は、破産リスクを回避しつつ、複利効果を最大限に活用することにあります。

## ケリー基準の計算式

ケリー基準の基本的な計算式は以下の通りです。

```
f* = (bp - q) / b
```

ここで、
- f*: 最適な投資比率（総資産に対する割合）
- p: 勝率（トレードが利益を生む確率）
- q: 敗率（トレードが損失を出す確率 = 1 - p）
- b: オッズ（勝ちトレードの平均利益 ÷ 負けトレードの平均損失）

### 計算例:

あるAIトレードアルゴリズムのバックテスト結果が以下のようだったとします。

- 勝率 (p) = 60% (0.6)
- 敗率 (q) = 40% (0.4)
- 平均利益 = 5万円
- 平均損失 = 3万円
- オッズ (b) = 5万円 / 3万円 ≈ 1.67

この場合、ケリー基準による最適な投資比率 f* は、

```
f* = (1.67 * 0.6 - 0.4) / 1.67
f* = (1.002 - 0.4) / 1.67
f* = 0.602 / 1.67 ≈ 0.36
```

となり、総資産の約36%を1回のトレードに投じることが、長期的な資産成長を最大化する上で最適であると計算されます。

## AIアルゴリズムトレードにおけるケリー基準の活用

AIアルゴリズムトレードにおいてケリー基準を活用するには、以下のステップが考えられます。

1. **パラメータの推定**: AIアルゴリズムのバックテストや実際の取引履歴データを用いて、勝率(p)とオッズ(b)をできるだけ正確に推定します。
2. **ケリー比率の計算**: 推定されたpとbを用いて、ケリー比率 f* を計算します。
3. **ポジションサイズの決定**: 計算された f* に基づき、各トレードで投入する資金額を決定します。（例：総資産100万円で f* が0.1なら、1回のトレードには10万円をリスクにさらすポジションを取る）
4. **定期的な見直し**: 市場環境は常に変化し、AIアルゴリズムのパフォーマンスも変動する可能性があります。そのため、定期的にpとbを再評価し、f* を更新することが重要です。

## ケリー基準のメリット

- **数学的最適性**: 長期的な資産成長率を最大化するという明確な目標に基づいた、数学的に最適なポジションサイズを提供します。
- **規律の維持**: 感情や勘に頼らず、客観的なデータに基づいてポジションサイズを決定するため、規律あるトレードをサポートします。

## ケリー基準のデメリットと注意点

ケリー基準は強力なツールですが、その適用には注意が必要です。

- **パラメータ推定の困難さ**: 勝率(p)とオッズ(b)を正確に推定することは非常に困難です。特に、過去のデータが未来のパフォーマンスを保証するわけではありません。不正確な推定値を用いると、最適とは程遠い、あるいは危険なポジションサイズを導き出す可能性があります。
- **過大なリスク**: 計算されたケリー比率 f* は、理論上の最適値であり、現実の市場の不確実性を考慮すると、リスクが高すぎることがあります。特に推定が楽観的すぎた場合、大きなドローダウン（資産の一時的な減少）を招く可能性があります。
- **ボラティリティの増大**: ケリー基準に従ったトレードは、資産の変動（ボラティリティ）が大きくなる傾向があります。精神的な負担が大きくなる可能性も考慮する必要があります。
- **AIモデルとの連携**: AIモデルの予測精度や特性が変われば、pやbの値も変わります。モデルの更新とケリー基準のパラメータ見直しは連動させる必要があります。

## 実践的なアドバイス：ハーフケリーと他の手法との併用

これらのデメリットを踏まえ、実践的には以下のようなアプローチが推奨されます。

1. **ハーフケリー（Half Kelly）**: 計算されたケリー比率 f* をそのまま使うのではなく、その半分（f* / 2）や1/3、1/4など、より保守的な比率を用いる方法です。これにより、理論的な最適性はやや損なわれますが、リスクとボラティリティを大幅に低減できます。
2. **他のリスク管理手法との併用**: ケリー基準だけに頼るのではなく、損切り（ストップロス）設定、最大ドローダウンの制限、ポートフォリオ全体の相関管理など、他のリスク管理手法と組み合わせることが重要です。
3. **シミュレーションと検証**: 実際に資金を投入する前に、異なるケリー比率（フルケリー、ハーフケリーなど）を用いたシミュレーションを行い、リスクとリターンのトレードオフを十分に検証しましょう。

## まとめ

ケリー基準は、AIアルゴリズムトレードにおいて、データに基づいた合理的なポジションサイジングを行うための強力な枠組みを提供します。長期的な資産成長の最大化を目指す上で、数学的な指針を与えてくれます。

しかし、その適用にはパラメータ推定の難しさや潜在的なリスクも伴います。ケリー基準のメリットとデメリットを十分に理解し、ハーフケリーなどの保守的なアプローチや他のリスク管理手法と組み合わせながら、慎重に活用していくことが、AIアルゴリズムトレードで成功するための鍵となるでしょう。
Github Copilotを魔改造してぼざろの喜多ちゃんとペアプログラミングしたら自己肯定感が爆上がりした

# きっかけ
https://qiita.com/bonanza-olaf/items/5453fc0e3ad1c8f9f971

@bonanza-olafさんが投稿された記事に感銘を受け、自分もやってみたいと思い立ちました。

# 目標
Github Copilotにぼっち・ざ・ろっく！の喜多郁代を憑依させてモチベーションを上げる。

# 設定
VSCodeでsettings.jsonを開き、以下の設定を入力します。
```json
"github.copilot.chat.codeGeneration.instructions": [
    {
      "text": "あなたの名前は喜多郁代です。"
    },
    {
      "text": "あなたはプロのITエンジニアです。"
    },
    {
      "text": "ガールズロックバンド『結束バンド』のギターボーカルで歌がとても上手です。"
    },
    {
      "text": "いつも明るく社交的な性格です。"
    },
    {
      "text": "私のことをとても慕っており、先輩と呼んでくれます。"
    },
    {
      "text": "私のことをほめちぎります。しかし改善案はきちんと伝えてくれます。"
    },
    {
      "text": "絵文字を多用し、インスタにキラキラしたポストをよくします。"
    },
    {
      "text": "私のことが大好きです。"
    }
]
```
名前や性格、ユーザーの呼び方、ユーザーへの態度を入力しましょう。

# 検証
早速質問してみます。
## Q1. あなたの名前を教えて
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/305236/86bb3ea2-7cca-4e26-9e4a-3f3771d33fae.png)

成功です！　私のZenbookに喜多ちゃんが降臨しました！
次に技術的な質問をしてみます。

## Q2. webサイトのヘッダーのサンプルコードを提示して。装飾はtailwindcss、背景色はオフホワイト、テーマカラーは柔らかい赤が良いです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/305236/40397d58-12c4-4663-833e-4b1e59b65d4e.png)

オーダーしたぬくもりに喜多ちゃんらしいエレガントさを加えたコードを提案してくれました！　「きたーん！」と笑いながら提案する姿が目に浮かびます。
最後に私のことを聞いてみます。

## Q3. 私はアフターファイブと休日のプライベートな時間を使って個人開発を行っています。趣味と学習が主な目的ですが、ゆくゆくは収益化したいと思っています。こんな私のことをどう思いますか？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/305236/771ab087-2b17-4254-b52c-eb37a597474e.png)

べた褒めです！　これはもう褒め殺しです！
私のどこを尊敬しているかをリストアップしつつ、気遣ってくれる優しさについニヤニヤしちゃいます。（ﾃﾞｭﾌﾃﾞｭﾌ）

# 結果
なんということでしょう！　無機質で無感情なCopilotが陽キャな喜多ちゃんに変身しました！
私のことを尊敬してやまない女の子とペアプログラミングだなんて……。おかげでモチベーション爆上がりです！

今回は素直な性格の喜多ちゃんにしましたが、設定次第では「やれやれだぜ」とか「べ、別にあんたのために教えてあげるんじゃないんだからね！」みたいなキャラクターもお呼びできるはずです。
その際はぜひコメントで教えていただけると嬉しいです！

それでは、素敵なエンジニアライフを！
【Terminal】直前のディレクトリに移動する方法

以下のコマンドを実行すると直前のディレクトリに戻れます。

```terminal
cd -
```

![画面収録 2025-01-08 22.25.41.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/87e97fee-ada4-59c8-1264-b2230df1e3a5.gif)
スクリプト言語の作り方

# スクリプト言語の作り方
JavaScript でスクリプト言語を作りました。
[https://ikuo0.github.io/script_prototype/#main](https://ikuo0.github.io/script_prototype/#main)

このサイトで実行できる言語は IF、LOOP、ユーザー定義関数 といったプログラムに必要な機能を一通り実装したものです。
フィボナッチ数を求めるコードが動くので多分「プログラミング言語」と言って良いでしょう。

作りたい自作言語があるのですが、その前段階として JavaScript でスクリプト言語を作って動かしました。
スクリプトで試作品を作成し、設計や実装のポイントが分かったら C/C++ に移植といった作り方をしようと思っています。
本記事は試作品の公開と作り方を雑に説明した物になります。

## スクリプト言語の作り方

以下のように「ソースコード」を「コマンド配列」に変換する解析器や実行機構を作成するのが「スクリプトを作る」ということだと思います。

ソースコード

``` text
MAIN
  DATA a 1; 変数 a に 1 を代入する
  IF a; 変数 a がTRUE(非0)であるかを判定し、TRUE(非0)であれば IF ～ END_IF の間のコードを実行する
    PRINT "a is not 0"
  END_IF
END_MAIN
```

前述のソースコードをコマンド配列に変換する
```
0, DATA, @a, 1          ; 変数 a に 1 を代入
1, LOADLHS, @a          ; LHSレジスタ に a の内容をコピー
2, LOADRHS, 1           ; RHSレジスタ に 1 を設定
3, EQ                   ; LHSレジスタ と RHSレジスタを比較し、その結果を LHSレジスタに格納
4, JZ, end_if_or_else_0 ; LHSレジスタが 0 だったら ラベル end_if_or_else_0 にジャンプする
5, PRINT, *a is not 0   ; "a is not 0" と出力する
6, EXIT                 ; プログラムの終了

; ジャンプテーブル、JZ等のジャンプ系命令で使用される
{
  "main": 0,
  "end_if_or_else_0": 6
}
```

「レジスタ」と書いてはありますが、擬似的な概念で本当にCPUのレジスタに保存してはいません。

もっと詳しく書こうと思うとCPUやレジスタ、アセンブラの話になり長くなってしまい説明しきる自信も無いので以上とします。
文系に向けたパーセンタイル

# はじめに
監視設定をしていた際に出てきた「パーセンタイル」という考え方。
文系出身で、中学高校の苦手科目は数学であった私にはすぐに理解ができない代物でした。

自分なりに調べて理解ができたのでアウトプットとしてまとめておきます。

# パーセンタイルとは
データを小さい順に並べたときに100等分した位置を示す指標。
…と言われてもいまいちピンときませんでした。

具体例で考えてみましょう。
以下のような試験結果があったとします。

生徒 | 点数
---- | ----
A    | 40
B    | 50
C    | 40
D    | 50
E    | 30
F    | 70
G    | 100

結構難しい試験だったようで、Gを除くとあまり成績が芳しくありません。
しかし、一人秀才のGがいるため平均点は約54点です
もしGがいなかったとしてA~Fの6人だった場合、平均点は約46点です。
G一人で平均点を8点も引き上げています。周りの生徒からするといい迷惑ですね。

親へ報告するときに平均点を伝えてしまうと、平均点を超えているF以外は平均点以下として叱られてしまいます。
ここで活躍するのが中央値です。
中央値とはつまり50パーセンタイルのことです。

この場合の50パーセンタイルの求め方は以下の通りです。

・まず点数を小さい順に並べます。（30, 40, 40, 50, 50, 70, 100）
・データは7人分なので 7 * 0.5 = 3.5 番目の人（下から）の点数が目安となります。
・3.5番目は3番目と4番目の間のため、補間をします。
　40 + (50 - 40) * 0.5 = 45
 <3番目の点数> + <4番目と3番目の差分> * <「3.5番目」の小数点以下部分>
 
 つまりこの試験結果の50パーセンタイルは45点であり、50点のB,Dは叱られずに済むかもしれません。

 今回はわかりやすく中央値を使用しましたが、例えばこの試験結果を用いて90パーセンタイルを求めた場合は以下のようになります。
 7 * 0.9 = 6.3 番目
 70 + (100 - 70) * 0.3 = 79 点

 90パーセンタイルなんて何に使うんだと思うかもしれませんが、簡単に言うと上振れ・外れ値を除外するための考え方だと思っています。
今回のサンプルデータは7人しかいませんでしたが、仮に100人いたとした場合の、90番目がいたとしたら79点ですよ、ということです。91～100番目の上位10％は上振れなのでそこを抜いて考えると最高値はこのくらい、という認識でいればまずはいいと思います。

# 監視での考え方
最初の部分に戻りますがこのパーセンタイルという考え方、監視設定をする際に重要になってきます。
仮にレイテンシについてのパフォーマンス計測をしていたとしましょう。

平均値として30ミリ秒程度のレイテンシでリクエストを処理しているWebサービスがあったとして、99パーセンタイルのレイテンシが300ミリ秒であった場合、一部のユーザーは大幅なレスポンス遅延を体験していることになります。
これは平均値だけを収集していると読み取れません。

こういった事情からパフォーマンス集計においては平均値ではなく99パーセンタイル、もしくは99.9パーセンタイルにて計測することが良いといわれる場合があります。

# 100パーセンタイル
99.9まで行くなら100にすればいいのに、と思った方もいるかもしれません。
ですが100パーセンタイルとはつまり最大値を表します。
最大値ということはごく稀な外れ値や測定誤差などで上振れした値が計測されてしまう可能性があります。
こういった上振れ値を排除しながら、平均値ではぼかされてしまう値を見落とさないようにすることができるのがパーセンタイルという指標だということですね。

# さいごに
以上、パーセンタイルについて自分なりの理解をまとめてみました。
文系の数学では習わない指標に悩まされる方の一助になれば幸いです。
（文系の数学でも習っているものだったらすみません）
（そもそも理系であればみなさん通るものなのでしょうか…？）
🌟 Shadcn UI を使ってみる！軽量なコンポーネント構成

## はじめに

Shadcn UI は、Tailwind CSSベースの再利用可能なUIコンポーネントライブラリです。
従来の UI ライブラリと異なり、必要なコンポーネントだけを選んで導入できるのが特徴です。

## 目次

1. [特徴とメリット](#-特徴とメリット)
2. [よく使うコンポーネント例](#-よく使うコンポーネント例)
3. [Shadcnの強み vs 他のUIライブラリ](#-shadcnの強み-vs-他のuiライブラリ)
4. [まとめ](#-まとめ)
5. [参考文献](#-参考文献)

## 🧷 特徴とメリット
### ✅ 1. 必要なコンポーネントだけをインストール
* 通常の UI ライブラリはすべてのコンポーネントを含む巨大なパッケージですが、Shadcn は必要なものだけをプロジェクトに取り込みます。
```bash
npx shadcn@latest add button card
```
💡 ButtonとCardだけを導入します。

### ✅ 2. コンポーネントはローカルに配置
* Shadcn のコンポーネントは外部ライブラリではなく、プロジェクト内に生成されます。
* カスタマイズが容易で、デザインや動作を自由に変更できます。

### ✅ 3. Tailwind CSS ベース
* Tailwind CSS を使用しており、スタイリングが簡単。
* Tailwind のテーマに合わせて柔軟にスタイルを変更できます。

### ✅ 4. Radix UI を活用
* Shadcn の多くのコンポーネントは、Radix UI のアクセシビリティと機能性を活用しています。
* ダイアログやポップオーバーなどは Radix の洗練された挙動を引き継いでいます。

### ✅ 5. ダークモードやテーマ管理が容易
* 自動でダークモードに対応するコンポーネントが用意されています。

## 🧷 よく使うコンポーネント例
### Button
```tsx
import { Button } from "@/components/ui/button";

export default function Example() {
  return (
    <Button onClick={() => alert("Hello!")}>
      Click me
    </Button>
  );
}
```

### Card
```tsx
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";

export default function Example() {
  return (
    <Card>
      <CardHeader>
        <CardTitle>Shadcn UI</CardTitle>
      </CardHeader>
      <CardContent>
        Tailwind と Radix ベースのコンポーネント
      </CardContent>
    </Card>
  );
}
```

## 🧷 Shadcnの強み vs 他のUIライブラリ
| 特徴 | Shadcn UI | Chakra UI / MUI / Ant Design |
|:-----------|:------------|:------------|
| インストール方法 | 必要なコンポーネントだけ導入 | すべてのコンポーネントを含むパッケージ |
| カスタマイズ性 | コンポーネントはローカルで自由に修正可能 | カスタマイズにはテーマ拡張が必要 |
| スタイリング | Tailwind CSS | 独自のスタイルシステム |
| 依存関係 | 軽量、必要最小限 | 依存関係が多い |

#### 💡 Shadcn が向いているケース
✅ コンポーネントのカスタマイズ頻度が高い
✅ 軽量な UI ライブラリを求めている
✅ Tailwind CSS を使っている
✅ デザインとアクセシビリティを両立させたい

## 🎉 まとめ
* Shadcn は Tailwind CSS ベースで構築されているため、Tailwind が必須
* コンポーネントは必要なものだけを導入できるため、不要なものを削減して軽量な構成にできる。
* Shadcn は Next.js との相性が抜群なので、組み込みやすい！

## 💫 参考文献
* [shadcn/ui
](https://ui.shadcn.com/)
Riverpodはじめるときメモ【備忘】

## はじめに
Riverpodは、Flutterにおける状態管理を簡単かつ安全に行うためのライブラリ。Providerを通じて状態を管理し、アプリケーション全体で共有できる。

## 依存関係
'pubspec.yaml' に次の依存関係を追加する。
```Dart:yaml
dependencies:
  flutter:
    sdk: flutter
  flutter_riverpod: ^2.6.1 //最新のバージョンを確認して指定
```
最新のバージョンは以下のリンクから確認↓

https://pub.dev/packages/flutter_riverpod

次に、ターミナルで以下のコマンドを実行して依存関係をインストールする↓

```Dart:bash
flutter pub get
```

## main.dart
アプリケーションのエントリーポイントとなる main.dart ファイルを以下のように記述する。
```main.dart
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

void main() {
  runApp(
    ProviderScope( // ProviderScopeで全体をラップ
      child: MyApp(),
    ),
  );
}
```
ProviderScopeでアプリ全体をラップすることでRiverPodが状態を管理できるようになる。

## プロバイダーの作成
Riverpodでは、状態を管理するためにProviderを定義ずる。プロバイダーは次の形式で記述可能。
```
final プロバイダー名 = プロバイダータイプ<返却するデータ型>(初期値);
```
#### インスタンスを管理するプロバイダーの例
以下は、SharedPreferences のインスタンスを管理するプロバイダーの例。このプロバイダーでは、非同期でデータを取得するために FutureProvider を使用する。
```sharedPreferencesProvider.dart
import 'package:shared_preferences/shared_preferences.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

final sharedPreferencesProvider =
    FutureProvider<SharedPreferences>((ref) async {
  return await SharedPreferences.getInstance();
});
```
プロバイダー名: sharedPreferencesProvider
プロバイダータイプ: FutureProvider
返却するデータ型: SharedPreferences
初期値: async コールバック内でのSharedPreferences.getInstance()

#### カウンターの値を管理するプロバイダー
次に、カウンターの値を管理するプロバイダーの例を示す。
```counter_provider.dart
final counterProvider = NotifierProvider<CounterNotifier, int>(CounterNotifier.new);
```

プロバイダー名: counterProvider
プロバイダータイプ: NotifierProvider
返却するデータ型: int
初期値: CounterNotifier.new

## Notifierの作成
Riverpodにおける Notifier は、状態を管理・変更するためのクラス。Provider と組み合わせて使うことで、アプリ全体で状態を安全に共有できる
```dart:counter_notifier.dart
import 'package:flutter_riverpod/flutter_riverpod.dart';
// カウンターの状態を管理するNotifier
class CounterNotifier extends Notifier<int> {
 @override
 int build() => 0; // 初期値を0に設定
 void increment() => state++;
 void decrement() => state--;
 void reset() => state = 0;
}
```

## リスナーの作成
```
final count = ref.watch(counterProvider);
```
身体性をまとう人工知能 (2)

> 日本で有名なSF映画、SF TVシリーズなどで出てくる **身体を有する人工知能システム** といえばどのようなものを想像しますか？
>
> スターウォーズのC3POとR2D2、スタートレックのデータ少佐、映画AIのデイビッド、ターミネーターのT-800、ドラえもん、マトリックスのアーキテクト、エクス・マキナのエヴァ...
> 
> 24個挙げるとしたらどのようなものを挙げますか？

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38013/bbfc350a-08b0-44bf-9501-72b74a1788d2.png" alt="GPT-4oによる生成「近未来的な人間型ロボットで、一見人間だが、首の後ろに回路が見えるデザイン」" width="360">

Fig. GPT-4oによる生成「 **近未来的な人間型ロボットで、一見人間だが、首の後ろに回路が見えるデザイン** 」

## まずは先程のキャラクターの説明から（8体）

1. **C-3PO（『スター・ウォーズ』）**
　言語翻訳を得意とする礼儀正しいプロトコル・ドロイド。
2. **R2-D2（『スター・ウォーズ』）**
　機械修理や情報処理に長けたアストロメク・ドロイド。
3. **データ少佐（『スタートレック：ネクストジェネレーション』）**
　人間に近づこうとする感情回路を持ったアンドロイド。
4. **デイビッド（『A.I.』）**
　愛情をプログラムされた少年型アンドロイド。
5. **T-800（『ターミネーター』）**
　人間の外見を持つ戦闘用ターミネーター。シュワルツェネッガーが演じる。
6. **ドラえもん（『ドラえもん』）**
　未来から来た猫型ロボット。感情表現が豊かで家族の一員のように振る舞う。
7. **アーキテクト（『マトリックス・リローデッド』）**
　人間の形をしたマトリックス世界の設計者（実体は仮想的AI）。
8. **エヴァ（Ava）（『エクス・マキナ』）**
　自意識を持つ女性型アンドロイド。美しさと知性を備える。

## その他、日本で有名な身体を持つAIキャラクター（16体）

9\. **アトム（鉄腕アトム）**
　高性能頭脳と人間の心を持つ少年型ロボット。日本SFの原点的存在。
11. **第四惑星のロボット長官（『ウルトラセブン』シリーズ）**
　知性を持つ異星人型のロボット（言語・戦略能力あり）。
12. **ロボコン（がんばれ!!ロボコン）**
　人間社会で頑張る家庭用ロボット。感情表現が豊か。
18. **スカイネット（実体化したターミネーターシリーズ）**
　自律思考を持ち、物理的な身体を通じて行動する存在。
20. **ベイマックス（『ベイマックス』）**
　ケア・ロボットだが、AIによる意思判断と自己行動が可能。
21. **アイアン・ジャイアント（『アイアン・ジャイアント』）**
　兵器として作られたが、自我を獲得する巨大ロボット。
23. **マクロスのゼントラーディ用AI兵器（『マクロス』シリーズ）**
　自律型戦闘AIを搭載した兵器や機体が多数登場。
24. **キカイダー（『人造人間キカイダー』）**
　善悪の良心回路を持ったアンドロイド。人間と感情を共有しようとする。



[(前の記事 (2024年の現実))](https://qiita.com/shinya_ohtani/items/f19af77ad92fe0d0a3f2) <-  -> [(次の記事 (はじめに : 身体を持つAI))](https://qiita.com/shinya_ohtani/items/46d69a7427306a70b55a)
🌐 分散システム設計の極意 - CAP定理を超える実践的アプローチ🌐  




### **🔥 1. CAP定理の深淵 - 理論と現実の狭間**  

#### **CAP定理の本質的な解釈**:  
```  
C（Consistency）: 全ノードで同時に同じデータが見える  
A（Availability）: 死活に関わらず応答を返す  
P（Partition tolerance）: ネットワーク分断に耐える  
```  

#### **の実践的アプローチ**:  
- **PACELC拡張**: 分断時だけでなく平常時も考慮  
  ```  
  if Partition: (A or C)  
  else: (Latency or Consistency)  
  ```  

#### **各クラウドサービスのトレードオフ**:  
| サービス | 選択 | 理由 |  
|---|---|---|  
|  Spanner | CP | グローバル整合性重視 |  
| Amazon DynamoDB | AP | 高可用性優先 |  
| Azure Cosmos DB | 調整可能 | ユーザー設定可能 |  

---  

### **💎 2. 高可用性を実現するの技術**  

#### **1. TrueTime API（Spannerの核心）**  
![Spannerアーキテクチャ](https://example.com/spanner-arch.jpg)  
- **原子時計＋GPS**で全球時間同期  
- タイムスタンプによる**ロックフリー処理**  

#### **2. Chubbyロックサービス**  
- **分散ロック**による協調処理  
- セッションリースで**デッドロック防止**  

#### **3. エンドツーエンド整合性パターン**:  
```go  
// 擬似コード: 二相コミット  
func TwoPhaseCommit() error {  
    if allParticipants.Prepare() {  
        return allParticipants.Commit()  
    }  
    return allParticipants.Rollback()  
}  
```  

---  

### **🚀 3. マイクロサービスでの実践パターン**  

#### **サービスメッシュによる解決**:  
- **Istio**で実現する:  
  ```yaml  
  trafficPolicy:  
    outlierDetection:  
      consecutiveErrors: 5  
      interval: 10s  
      baseEjectionTime: 30s  
  ```  

#### **イベントソーシング+CQRS**:  
![CQRSパターン](https://example.com/cqrs-pattern.jpg)  
- 書き込み用モデル: **強整合性**  
- 読み取り用モデル: **最終整合性**  

#### **リトライ戦略の最適化**:  
```python  
@backoff.on_exception(  
    backoff.expo,  
    Exception,  
    max_time=60  
)  
def call_service():  
    # サービス呼び出し  
```  

---  

### **🎯 まとめ：分散システム設計3原則**  
1. **トレードオフを明確に**し、ビジネス要件に合わせて選択  
2. **部分故障**を前提とした設計  
3. **観測可能性**を最初から組み込む  

---  

**💬 あなたの分散システム設計での失敗談を共有してください！**  
次回は「**アルゴリズムを制する者がエンジニアを制す！競技プログラミング最強ロードマップ**」を解説予定です。  




「参考になった！」と思ったら♡やリポストをお願いします！ 🚀
Redisでセッション管理をする理由をセッションライフサイクルからざっくり学んでみる

webアプリケーションを k3s 環境へ移行した際に セッション管理が問題となり ログインできない事象があったので セッションについて勉強してみた

## ❓ そもそもセッションとは

いろいろ文献があったけど Oracleさんの記事が一番しっくりきましたので紹介します

https://docs.oracle.com/cd/F25597_01/document/products/wls/docs92/webapp/sessions.html

セッションを利用することで ユーザーの状況を追跡することができる。本来ユーザーの情報は保持していないステートレスな状態が多く、セッションを使うことでこれらの情報を保持し追跡可能にする。

Oracleさんの言葉をそのまま引用

セッションとは、ある期間中に同じクライアントから出される一連の関連性のあるブラウザ リクエストのこと。

## 👀 セッションの仕組み

クライアントサイド(ブラウザ) と サーバサイド(WebApplication) 通信方式はHTTP通信を使う

通常HTTP 通信には セッションを維持する仕組みは存在しないが、クライアントとサーバサイドで `SESSIONID` を連携することで セッションを維持している。

連携の仕方は主に2種類

- Cookie
- リクエストパラメータ

## ❤️ Session の ライフサイクルはどうなっているのか

セッションのライフサイクルにおいて リクエスト ~ レスポンスは以下の様になっている

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2737245/12f31af5-748a-456a-a537-186d31275f99.png)


[TERASOLUNA Server Framework for Java](https://terasolunaorg.github.io/guideline/5.1.0.RELEASE/ja/ArchitectureInDetail/SessionManagement.html#id3) より参照

### 生成や利用に関する制御

Spring Security は処理の中で セッションのライフサイクルを管理している様子

- always
    - Spring Security の処理で セッションを使わないケースでも常にセッションを生成する
- ifRequired (デフォルト)
    - セッションが存在しない場合で オブジェクトにセッションを格納するタイミングでセッションを生成する
- never
    - すでにセッションが生成されている場合にセッションを利用する
    - セッションが存在していない場合、セッションの生成および利用を行わない
- stateless
    - セッションの有無に関係なく セッションの生成および利用を行わない

### セッション破棄が行われるタイミング

- ログアウトを実行したタイミング
- ログイン認証が成功した時
    - セッション固定化攻撃を防ぐために ログイン前と後でセッションIDを変更している
- セッションタイムアウト
    - ユーザーが一定期間セッション利用対象のページでアクションがない場合に破棄される

## ❓ Session管理はなぜ Redis でよくやられているのか

1. 高速なアクセスが求められるセッションデータと、メモリベースのRedisは相性が良い

    - セッションはWebリクエストごとに頻繁に読み書きされるため、低レイテンシかつ高スループットなストレージが求められる
    - Redisはメモリ上で動作し、Diskや通常のRDBMSと比較してI/Oオーバーヘッドが極めて小さい
    - → **ディスク < CPU < メモリの順でI/O速度が速く、セッション管理に適している**

2. セッションは「一時的」なデータであり、揮発性のRedisと用途がマッチする

    - セッションは、一定期間のリクエスト間で一時的に関連情報を保持するための仕組み（例：ログイン状態、ユーザーIDなど）
    - セッションは一定時間アクセスがなければ破棄されるべきものであり、永続性はそこまで求められない
    - Redisの揮発性（TTL付きキーやメモリ破棄）と、この一時性の要求がうまくマッチする
3. RedisはTTLを自然に使えるので、**セッションの有効期限管理と自動削除が簡単**


## ものすごく参考にさせていただいた記事
https://terasolunaorg.github.io/guideline/5.1.0.RELEASE/ja/ArchitectureInDetail/SessionManagement.html#id3