<?xml version="1.0" encoding="UTF-8"?>
<rdf:RDF
 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 xmlns="http://purl.org/rss/1.0/"
 xmlns:content="http://purl.org/rss/1.0/modules/content/"
 xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/"
 xmlns:dc="http://purl.org/dc/elements/1.1/"
 xmlns:syn="http://purl.org/rss/1.0/modules/syndication/"
 xmlns:admin="http://webns.net/mvcb/"
 xmlns:atom="http://www.w3.org/2005/Atom"
>
<channel rdf:about="http://www.otupy.net/">
<title>乙Py先生のプログラミング教室</title>
<link>http://www.otupy.net/</link>
<description>乙Py先生のプログラミング教室
</description>
<dc:language>ja</dc:language>
<admin:generatorAgent rdf:resource="http://blog.livedoor.com/?v=2.0" />
<atom:link rel="hub" href="http://pubsubhubbub.appspot.com" />
<items>
 <rdf:Seq>
  <rdf:li rdf:resource="http://www.otupy.net/archives/44041723.html" />
  <rdf:li rdf:resource="http://www.otupy.net/archives/48331173.html" />
  <rdf:li rdf:resource="http://www.otupy.net/archives/48303953.html" />
  <rdf:li rdf:resource="http://www.otupy.net/archives/48249362.html" />
  <rdf:li rdf:resource="http://www.otupy.net/archives/48227375.html" />
  <rdf:li rdf:resource="http://www.otupy.net/archives/48205813.html" />
  <rdf:li rdf:resource="http://www.otupy.net/archives/48162963.html" />
  <rdf:li rdf:resource="http://www.otupy.net/archives/48139010.html" />
  <rdf:li rdf:resource="http://www.otupy.net/archives/41090674.html" />
  <rdf:li rdf:resource="http://www.otupy.net/archives/48052118.html" />
 </rdf:Seq>
</items>
</channel>
<item rdf:about="http://www.otupy.net/archives/44041723.html">
<title>[Flutter]アプリをリリースしてみた</title>
<link>http://www.otupy.net/archives/44041723.html</link>
<description>今回はアプリをリリースしたのでそちらのご報告です。解説動画はこちらアプリについて今回作成したアプリはこちらです・チャンクde英会話iOS

Android良かったら使ってみてくださいアプリの作成方法Flutterを用いて作成しましたFlutterにした理由は　1.iOSとAndroid両対応で...</description>
<dc:creator>otupython</dc:creator>
<dc:date>2028-01-06T17:37:53+09:00</dc:date>
<dc:subject>プログラミング</dc:subject>
<content:encoded><![CDATA[今回はアプリをリリースしたので<br />そちらのご報告です。<br /><br />解説動画はこちら<br /><iframe  height="315" width="560" src="https://www.youtube.com/embed/LkAo9wPqCj0" allowfullscreen="" frameborder="0" style="vertical-align:top;" allowfullscreen></iframe><br /><br /><br /><span  style="font-size: 150%;">アプリについて</span><br /><br /><br />今回作成したアプリはこちらです<br /><br /><div>・チャンクde英会話<br /><br />iOS<br /><a  href="https://apps.apple.com/jp/app/%E3%83%81%E3%83%A3%E3%83%B3%E3%82%AFde%E8%8B%B1%E4%BC%9A%E8%A9%B1/id6475059252" target="_blank" rel="noopener noreferrer">
<img  class="pict" hspace="5" alt="AppStore" border="0" height="125" width="340" src="https://livedoor.blogimg.jp/otupython/imgs/2/f/2f11c74d.png">
</a><br /><br /><br />Android<br /><a  href="https://play.google.com/store/apps/details?id=com.dcllc.chunkenglish&amp;hl=ja-JP" target="_blank" rel="noopener noreferrer"><img  class="pict" hspace="5" alt="Googleplay" border="0" height="120" width="400" src="https://livedoor.blogimg.jp/otupython/imgs/9/d/9d442cf3.png"></a><br /><br />良かったら使ってみてください<br /><br /><br /><span  style="font-size: 150%;">アプリの作成方法</span><br /><br />Flutterを用いて作成しました<br /><br />Flutterにした理由は<br />　1.iOSとAndroid両対応であること<br />　2.学習コストが低い<br />　3.文献が豊富で有る<br /><br />以上の理由からFlutterにしてみました。<br /><br />それ以外にもアプリを作る方法は<br />いくらでもありますが、今回は<br />Flutterを使ってみました。<br /><br />開発言語がDartになるので<br />1から勉強することになります。<br /><br />また、コードやデータなどの大半は<br />ChatGPTを用いて作成していますので<br />実質ChatGPTに頼れば<br />アプリの開発は容易かと思います。<br /><br />学習開発の期間で2ヶ月くらいでした。<br /><br /><br /><br /><span  style="font-size: 150%;">リリースについて</span><br /><br />コードを実装しシミュレータや<br />実機でのテストが終わったら<br />ビルドを行なってアプリを作り<br />リリース準備ができます。<br /><br /><br />その前にアプリストアのアカウントがないと<br />そもそもリリース出来ないので<br />アプリストアのアカウント取得が必要です。<br /><br />これもそこそこ手間と時間が掛かります。<br /><br />リリース登録をしたら審査が行われますが<br />審査に通らなければビルドからやり直し<br />審査に通るまでの繰り返しです。<br /><br />審査に通ったらようやく<br />リリース、アプリ配信ができる様になります。<br /><br />リリース作業を始めてから<br />アカウント登録とアプリリリースまでで<br />大体1ヶ月くらい掛かっています。<br /><br /><br /><br /><span  style="font-size: 150%;">Flutterについて</span><br /><br />動画の方では少しだけ解説していますが<br />FlutterはiOSとAndroidの両方のアプリを<br />作成する事ができる開発フレームワークです。<br /><br />Flutterをインストールしたら<br />VSCodeなどでコードを書き進める事が<br />できる様になります。<br /><br />テストやビルドなども<br />Flutterコマンドを用いて行う形になります。<br /><br />この辺りも<br />VSCodeと合わせておくと<br />開発が楽になるかなと思います。<br /><br />どんな感じなのかは<br />動画の方で解説していますので<br />参考にしていただければと思います。<br /><br /><br /><span  style="font-size: 150%;">最後に</span><br /><br />これからアプリ開発を行いたい方にとっては<br />色々な選択肢があると思いますが<br />Flutterを使ってアプリを開発したい方が<br />増えていただけたら幸いです。<br /><br />Python言語の解説と共に<br />アプリ開発の方も進めていきますので<br />要望などあれば是非コメントいただければと思います。<br /><br />それでは。<br /><br /></div>
]]>
</content:encoded>
</item>
<item rdf:about="http://www.otupy.net/archives/48331173.html">
<title>[Pythonプログラミング]国士無双13面待ちの確率は?</title>
<link>http://www.otupy.net/archives/48331173.html</link>
<description>あの伝説の国士無双13面待ちこれが出る確率を求めてみました。解説動画はこちら国士無双13面待ちが出る確率は?今回は麻雀ネタです。麻雀における最高峰の役「役満」の一つに「国士無双」という役満があります13種類の么九牌（一九字牌）を各1枚以上集める特殊な形の役満です...</description>
<dc:creator>otupython</dc:creator>
<dc:date>2026-04-11T17:45:00+09:00</dc:date>
<dc:subject>プログラミング</dc:subject>
<content:encoded><![CDATA[あの伝説の国士無双13面待ち<br />これが出る確率を求めてみました。<br /><br />解説動画はこちら<br /><iframe  height="315" width="560" src="https://www.youtube.com/embed/f4SD_duMOFs" allowfullscreen="" frameborder="0" style="vertical-align:top;" allowfullscreen></iframe><br /><br /><span  style="font-size: 150%;">国士無双13面待ちが出る確率は?</span><div><br /><br />今回は麻雀ネタです。<br /><br />麻雀における最高峰の役「役満」の一つに<br />「国士無双」という役満があります<br /><br />13種類の么九牌（一九字牌）を<br />各1枚以上集める特殊な形の役満です。</div><div><br /><br />13面待ち</div><div>萬子・索子・筒子の1・9、東・南・西・北・白・發・中の<br />計13種類をすべて揃えた状態でアガリ待ちの状態のことです。<br /><br /><a  target="_blank" title="13" href="https://livedoor.blogimg.jp/otupython/imgs/4/5/45f55835.png"><img  class="pict" hspace="5" alt="13" border="0" height="64" width="480" src="https://livedoor.blogimg.jp/otupython/imgs/4/5/45f55835-s.png"></a><br /><br /><br /><br />この13面待ちがどれくらいの確率でやってくるのか<br />プログラムで求めていきたいと思います。<br /><br /><br /><br /></div><span  style="font-size: 125%;">1.接待麻雀モード</span><br /><br />自分一人がずっと国士無双13面待ちを狙い<br />他はただパイを捨て続けるとした場合の確率です。<br /><br /><br /><br />簡易に求めるコード<br /><pre  class="brush:py">import random

# ヤオ九牌（1, 9, 字牌）のインデックス定義
YAOCHU_INDICES = [0, 8, 9, 17, 18, 26, 27, 28, 29, 30, 31, 32, 33]

def is_kokushi_13men_machi(tehai):
    """
    国士無双13面待ちの判定
    13種類のヤオ九牌がすべて1枚ずつ揃っているか
    """
    for idx in YAOCHU_INDICES:
        if tehai[idx] &lt; 1:
            return False
    return True

def simulate_one_game_kokushi():
    # 山の作成（136枚）
    yama = []
    for i in range(34):
        yama.extend([i] * 4)
    random.shuffle(yama)

    # 全員の手牌（4人分）
    players_tehai = [[0] * 34 for _ in range(4)]
    
    # 配牌（各13枚）
    for p in range(4):
        for _ in range(13):
            pai = yama.pop()
            players_tehai[p][pai] += 1

    turn = 0
    while len(yama) &gt; 14:
        turn += 1
        for p in range(4):
            # --- 1. ツモ ---
            tsumo_pai = yama.pop()
            players_tehai[p][tsumo_pai] += 1

            # --- 2. 判定（プレイヤー0のみ国士無双を判定） ---
            if p == 0 and is_kokushi_13men_machi(players_tehai[p]):
                return True, turn, p

            # --- 3. 捨て牌選択 ---
            if p == 0:
                # プレイヤー0: 国士無双を狙う戦略
                discard_candidates = []
                
                # 優先順位1: 中張牌を捨てる
                for i in range(34):
                    if i not in YAOCHU_INDICES and players_tehai[p][i] &gt; 0:
                        discard_candidates.extend([i] * players_tehai[p][i])
                
                # 優先順位2: 被っているヤオ九牌を捨てる
                if not discard_candidates:
                    for i in YAOCHU_INDICES:
                        if players_tehai[p][i] &gt;= 2:
                            discard_candidates.append(i)

                # 優先順位3: どれでも（13面待ち完成中など）
                if not discard_candidates:
                    discard_candidates = [i for i, count in enumerate(players_tehai[p]) if count &gt; 0]
                
                discard_pai = random.choice(discard_candidates)
            else:
                # 他のプレイヤー: ツモ切り（今引いた牌をそのまま捨てる）
                discard_pai = tsumo_pai

            players_tehai[p][discard_pai] -= 1
            
            # 山がなくなったら終了（流局）
            if len(yama) &lt;= 14:
                break
                
    return False, turn, None

def run_kokushi_experiment(episodes_per_step=10000):
    print(f"国士無双13面待ちシミュレーション ({episodes_per_step}局)\n")
    print("成立回数 | 成立確率 | 平均巡目")
    print("-----------------------------------------")

    success_count = 0
    total_turns = 0
        
    for _ in range(episodes_per_step):
        is_clear, turns, winner = simulate_one_game_kokushi()
        if is_clear:
            success_count += 1
            total_turns += turns
    
    prob = (success_count / episodes_per_step) * 100
    avg_turn = total_turns / success_count if success_count &gt; 0 else 0
    print(f"{success_count:4}回  | {prob:6.2f}% | {avg_turn:5.2f}巡")

run_kokushi_experiment(100000)</pre><div>国士無双13面待ちシミュレーション (100000局)</div><br /><div>成立回数 | 成立確率 | 平均巡目</div><div>-----------------------------------------</div><div>&nbsp;120回&nbsp; |&nbsp; &nbsp;0.12% | 16.44巡</div><br /><br /><br />接待麻雀モードになっていますが<br />10万局中120回<br />確率0.12%でした。<br /><br /><br /><br /><span  style="font-size: 125%;">2.他家が確率でアガるモード</span><br /><br />先ほどのプレイヤーがずっと国士無双を狙う状態で<br />他家が10巡目以降、確率でアガられてしまう状態の<br />確率を求めています。<br /><br /><br /><span  style="font-size: 125%;">3.13面待ちからアガる確率</span><br /><br />他家が確率でアガるモードに加えて<br />13面待ちから、上がれたかどうかの<br />確率も求めました。<br /><br />こちらはぜひ動画で確率をご覧ください。<br /><br /><br /><br />まとめ<br /><br /><div>国士無双13面待ちは、それなりにアガるプレイヤーがいても</div><div>10000局に1回位は見れると推測されるので</div><div>年間300試合、試合平均11局だと、3-4年に1回は<br />13面待ちの実況が見れるかもしれません。</div><div><br />13面待ちでアガリの確率はさらに低いので(一生に一度出せるかどうか)</div><div>もう10年は見れないかもしれないですね。<br /><br /><br />今回は麻雀ネタでしたが<br />次回も多分麻雀ネタです。<br />それでは。<br /><br /></div><br /><br />
]]>
</content:encoded>
</item>
<item rdf:about="http://www.otupy.net/archives/48303953.html">
<title>[Pythonプログラミング]緋色の弾丸シミュレーション-銀の弾丸はどこまで飛んでいくか</title>
<link>http://www.otupy.net/archives/48303953.html</link>
<description>今回は名探偵コナンの緋色の弾丸シミュレーションです。解説動画はこちら緋色の弾丸『名探偵コナン 緋色の弾丸』2021年4月16日公開のアニメ映画で劇場版『名探偵コナン』シリーズの24作目です。映画の中ではリニアの超高速移動に合わせて数キロ以上の距離から、動く犯人の狙...</description>
<dc:creator>otupython</dc:creator>
<dc:date>2026-04-04T17:15:06+09:00</dc:date>
<dc:subject>プログラミング</dc:subject>
<content:encoded><![CDATA[今回は名探偵コナンの<br />緋色の弾丸シミュレーションです。<br /><br /><br />解説動画はこちら<br /><iframe  height="315" width="560" src="https://www.youtube.com/embed/_J0uJyk6oIo" allowfullscreen="" frameborder="0" style="vertical-align:top;" allowfullscreen></iframe><br /><br /><br /><br /><span  style="font-size: 150%;">緋色の弾丸</span><br /><br /><div>『名探偵コナン 緋色の弾丸』</div><div><br />2021年4月16日公開のアニメ映画で<br />劇場版『名探偵コナン』シリーズの24作目です。</div><div><br />映画の中ではリニアの超高速移動に合わせて<br />数キロ以上の距離から、動く犯人の狙撃に成功しているシーンがあります<br /><br />この弾丸の到達距離のシミュレーションを行なっていきます。<br /><br /><br /><span  style="font-size: 150%;">最長狙撃記録</span><br /><br />現代の主要な最長狙撃記録です。<br /><div>1位：約4,000m（2024年、ウクライナ軍、Snipex Alligator）</div><div>2位：3,800m（2023年、ウクライナ軍、MCR Horizon's Lord）</div><div>3位：3,540m（2017年、カナダ軍、TAC-50）</div><br />現実世界では3-4キロの到達が限界だと思われます。<br /><br /><br /></div><br /><br /><span  style="font-size: 150%;">映画上の設定</span><br /><br />映画上には狙撃を成功させるための<br />重要なポイントとなる設定がいくつかありました。<br /><div>世界初の「真空トンネル」内を走行する超電導リニアで時速は約1000km</div><div>ライフル弾には特注の「銀の弾丸」が使用された<br /><br /></div><div>リニアも弾丸も時速1000kmで飛んだ設定</div><div>リニアが減速した際に、ライフル弾は減速しないので、そのまま犯人に命中した</div><br />つまりは真空状態のリニア線路上を銀の弾丸が飛んでいったというのが<br />重要なポイントです。<br /><br /><br /><div><span  style="font-size: 150%;">銀の弾丸使用のポイント</span><br /><br /><br />狙撃用の弾の素材が銀が最良かどうかは分かりませんが<br />銀である必要はあったようです。<br /><br /><br /></div><div>高い導電性:</div><div>銀は金属の中で電気を通しやすい</div><br /><div>レンズの法則（渦電流）:</div><div>導体である銀が、リニアの強力な変動磁場の中を高速で移動すると<br />弾丸表面に強力な「渦電流」が発生</div><br /><div>磁気反発:</div><div>この渦電流が、レールの磁場と反発する磁力（ローレンツ力）を<br />生み出し、弾丸を浮かせる 「揚力」 となる</div><br /><div><br />ということで<br />リニア線路内は重力の影響を受けない弾丸になる<br />と仮定することにします。</div><br /><br /><div><span  style="font-size: 150%;">射撃シミュレーター</span></div><div><br />重力 0 や真空の状況を加味したものです<br /><br />通常射撃(空気抵抗、重力影響有り)</div><div>真空射撃(空気抵抗 0、重力影響有り)</div><div>リニア射撃(空気抵抗 0、重力影響 0)</div>の状態を選べます。<br /><br />コードはこちら<br /><pre  class="brush:py">import numpy as np
import matplotlib.pyplot as plt
from math import pi, cos, sin, sqrt

class BallisticSimulator:
    def __init__(self, dt=0.01):
        self.dt = dt
        self.g = 9.80665

    def get_accelerations(self, vx, vy, k, am):
        """
        現在の速度と設定から、x方向とy方向の加速度を返す
        k: 空気抵抗係数, am: 磁気浮上加速度
        """
        v = sqrt(vx**2 + vy**2)
        # x方向: 空気抵抗のみ
        ax = -k * vx * v
        # y方向: 重力(下) + 磁気浮上(上) + 空気抵抗(上下)
        ay = -self.g + am - (k * vy * v)
        return ax, ay

    def simulate(self, mode="normal", v0_kmh=1000.0, deg=0.0, ht=1.5, mas_g=9.0, area_cm2=0.5):
        # モードごとの環境設定
        config = {
            "normal":      {"rho": 1.225, "am": 0.0},      # 1. 通常（空気あり、浮力なし）
            "vacuum":      {"rho": 0.0,   "am": 0.0},      # 2. 真空（空気なし、浮力なし）
            "maglev":      {"rho": 0.0,   "am": 9.80665}   # 3. 真空 + 磁気浮上
        }
        env = config.get(mode, config["normal"])
        v0 = v0_kmh / 3.6
        rad = deg * pi / 180
        # 物理定数の計算
        mas = mas_g / 1000.0
        s_area = area_cm2 / 10000.0
        cd = 0.3
        k = 0.5 * s_area * cd * env["rho"] / mas
        # 初期値
        x, y = 0.0, ht
        vx, vy = v0 * cos(rad), v0 * sin(rad)
        res_x, res_y = [x], [y]
        for _ in range(1000000):
            k1vx, k1vy = self.get_accelerations(vx, vy, k, env["am"])
            k2vx, k2vy = self.get_accelerations(vx + k1vx*self.dt/2, vy + k1vy*self.dt/2, k, env["am"])
            k3vx, k3vy = self.get_accelerations(vx + k2vx*self.dt/2, vy + k2vy*self.dt/2, k, env["am"])
            k4vx, k4vy = self.get_accelerations(vx + k3vx*self.dt, vy + k3vy*self.dt, k, env["am"])
            vx += (k1vx + 2*k2vx + 2*k3vx + k4vx) / 6 * self.dt
            vy += (k1vy + 2*k2vy + 2*k3vy + k4vy) / 6 * self.dt
            x += vx * self.dt
            y += vy * self.dt
            if y &lt; 0 or x &gt;= 300000: break
            res_x.append(x)
            res_y.append(y)
        return res_x, res_y

# --- 実行と可視化 ---
sim = BallisticSimulator()
modes = ["normal", "vacuum", "maglev"]
mode = modes[1]

rx, ry = sim.simulate(mode=mode, v0_kmh=1000.0, deg=0)
print(f"飛行時間  : {(len(rx) - 1) * sim.dt:.2f} 秒")
print(f"移動距離  : {rx[-1]:.2f} メートル, {rx[-1]/1000:.5f} キロメートル")
plt.figure(figsize=(16, 3))
plt.plot(rx, ry, label=f"Mode: {mode}")
plt.axhline(0, color='black', linewidth=1)
plt.title("Comparison of Bullet Trajectories (v=1000km/h)")
plt.xlabel("Distance (m)")
plt.ylabel("Height (m)")
plt.legend()
plt.grid(True)
plt.show()</pre><div>飛行時間&nbsp; : 0.54 秒</div><div>移動距離&nbsp; : 150.00 メートル, 0.15000 キロメートル</div><br /><a  target="_blank" title="download-3" href="https://livedoor.blogimg.jp/otupython/imgs/1/6/161216ef.png"><img  class="pict" hspace="5" alt="download-3" border="0" height="115" width="480" src="https://livedoor.blogimg.jp/otupython/imgs/1/6/161216ef-s.png"></a><br /><br />&nbsp;真空状態であったとしても<br />水平に撃ったのでは150メートルほどしか飛びません。<br /><br /><br />上の方に向けて撃った場合はもう少し長い距離飛びます。<br /><br /><a  target="_blank" title="download-2" href="https://livedoor.blogimg.jp/otupython/imgs/5/0/50ef7606.png"><img  class="pict" hspace="5" alt="download-2" border="0" height="116" width="480" src="https://livedoor.blogimg.jp/otupython/imgs/5/0/50ef7606-s.png"></a><br /><br />射角5度くらいで1400メーターくらいです。<br />全然届かないですね。<br />しかも高さ30メートルの高低差が出てしまうので<br />リニアトンネルの天井にぶつかって終わってしまいます。<br /><br /><br />しかし、重力の影響が無いと仮定すると<br /><br /><a  target="_blank" title="download" href="https://livedoor.blogimg.jp/otupython/imgs/1/c/1c18869d.png"><img  class="pict" hspace="5" alt="download" border="0" height="115" width="480" src="https://livedoor.blogimg.jp/otupython/imgs/1/c/1c18869d-s.png"></a><br />銀の弾丸はまっすぐ飛んでいけます。<br /><br /><br /><br /><span  style="font-size: 150%;">まとめ</span><br /><br /><br /><div>弾丸が重力の影響を受けない限定的な条件下であれば</div><div>シミュレーション上ではトンネルが真っ直ぐ続く限り<br />銀の弾丸はどこまでも飛んでいくと推測されます。<br /><br /></div><div>狙撃距離は100kmあたり(2分後くらい)になると推測される</div><div><br />銀の弾丸に浮力が付き<br />リニアの線路がマジで真っ直ぐだったら<br />あり得ないでもない(赤井さんなら)</div>というのが結論です。<br /><br /><br />製作陣がどれだけの考慮をしたかは分かりませんが<br />特殊条件下であれば不可能でも無いと思います。<br /><br />そういえば<br />来週からコナンの新作映画が公開されますね！！<br /><br />速攻見にいきましょう<br /><br /><br />PS:<br />個人的には<br />逆襲のシャアの決着を<br />コナンで付けてもらいたかったのですが<br />もう叶わないのですかね<br /><br /><br /><br /><br /><br /><br />
]]>
</content:encoded>
</item>
<item rdf:about="http://www.otupy.net/archives/48249362.html">
<title>[Pythonプログラミング]Manimで美しい数式アニメーション作成</title>
<link>http://www.otupy.net/archives/48249362.html</link>
<description>今回は数式から美しいアニメーションを作成できるManimのご紹介です解説動画はこちらManimとはManim（Mathematical Animation Engine）数学や物理を視覚的に表現するためのPythonのアニメーションエンジンです。3Blue1Brownの制作者(Grant Sanderson)によって開発数学の教育...</description>
<dc:creator>otupython</dc:creator>
<dc:date>2026-03-21T17:31:00+09:00</dc:date>
<dc:subject>プログラミング</dc:subject>
<content:encoded><![CDATA[今回は数式から美しいアニメーションを作成できる<br />Manimのご紹介です<br /><br />解説動画はこちら<br /><iframe  height="315" width="560" src="https://www.youtube.com/embed/GjbPK_HWDm0" allowfullscreen="" frameborder="0" style="vertical-align:top;" allowfullscreen></iframe><br /><br /><br /><br /><br /><br /><span  style="font-size: 150%;">Manimとは</span><br /><br />Manim（Mathematical Animation Engine）<br />数学や物理を視覚的に表現するための<br />Pythonのアニメーションエンジンです。<br /><br /><div>3Blue1Brownの制作者(Grant Sanderson)によって開発<br />数学の教育動画で幅広く使用されています。</div><br />Python コードで数式やグラフをアニメーションとして<br />動画化してくれるライブラリです。<br /><br /><br /><div><span  style="font-size: 150%;">Manim を利用するうえで必要なこと</span></div><br /><div>関連ライブラリのインストール</div><div><div>&nbsp; &nbsp;- FFmpeg と必須ライブラリ</div><div>&nbsp; &nbsp;- LaTeX (MacTeX)&nbsp;</div><div>&nbsp; &nbsp;- Manim本体</div></div><div>Python の知識</div><div>TeX 記法の知識</div><br />この辺りが必要です。<br /><br /><br /><span  style="font-size: 150%;">関連ライブラリのインストール</span><br /><br /><div>Manimを動かすには以下の3つが必要です。<br /><br />1.FFmpeg と必須ライブラリ</div><div>2.LaTeX (MacTeX)&nbsp;<br />3.Manim本体<br /><br />早速インストールしていきましょう。<br /><br />こちらはMac用のインストールコマンドです。<br />(Windowsの人はMacを買うか、Macを買いましょう)<br /><br />1.FFmpeg と必須ライブラリのインストール<br /><br />Manimが動画を描画・出力するために必要なツールです。<br /><pre  class="brush:py">brew install ffmpeg py3cairo pkg-config
</pre><br /></div><br /><div>2.LaTeX (MacTeX) のインストール</div><br /><div>美しい数式を描画するためのLaTeX環境です。<br /><pre  class="brush:py">brew install --cask mactex-no-gui
</pre><br /><br /></div>3.Manim のインストール<br /><pre  class="brush:py">pip install manim
</pre><br /><br />インストール後の確認<br /><pre  class="brush:py">manim --version
</pre><br /><br /><br /><div><span  style="font-size: 150%;">基本的な使い方</span></div><br /><div><span  style="font-size: 125%;">ファイルを作成して実行する</span></div><br /><div>Pythonファイルとして作成した後</div><div>そのファイルをターミナルで実行することで<br />動画を作成できます。</div><br /><pre  class="brush:py">manim -pqh ファイル名 シーン名
</pre><br /><br /><div>&nbsp;- -p: レンダリング後に動画を自動再生</div><div>&nbsp;- -q: 品質 (l=低, h=高, k=4K)</div><div>&nbsp;- ファイル名 : hello.py</div><div>&nbsp;- シーン名 : Hello</div><br /><br /><div>動画ファイルの出力先は<br />media/videos/...</div><div>になる(デフォルト)</div><br />hello.py というファイルでサンプルを用意しました。<br />
<pre  class="brush:py"># hello.py
from manim import *

class Hello(Scene):
    def construct(self):
        text = Text("どうもこんばんわ、乙pyです")
        self.play(Write(text))
        self.wait()
</pre><br />実行方法は次のようになります。<br /><br />サンプルの実行<br /><pre  class="brush:py">manim -pqh hello.py Hello
</pre><br /><br /><br /><br /><div><span  style="font-size: 125%;">基本文法</span></div><br /><div>インポートとコンストラクタの定義</div><br />ライブラリをインポートして<br />コンストラクタを最初に定義します。<br /><pre  class="brush:py">from manim import *

class MyAnimation(Scene):
    def construct(self):
</pre><br /><br />コンストラクタを作ったら<br />描きたいものを定義していきます。<br /><br /><pre  class="brush:py">変数名 = オブジェクト名(引数など)

self.play(): 
アニメーションを実行

.animate: 
オブジェクトのプロパティ（位置や色）を滑らかに変化

ReplacementTransform: 
前の物体を消して、次の物体へモーフィング
</pre><br />オブジェクトを生成して動かすサンプルも用意しました。<br /><br />サンプルコード<br /><br /><pre  class="brush:py"># basicflow.py
# manim -pqh basicflow.py BasicFlow
from manim import *

class BasicFlow(Scene):
    def construct(self):
        # 1. オブジェクトの生成
        title = Text("Manimの基本操作", font_size=40)
        square = Square(color=BLUE, fill_opacity=0.5)
        circle = Circle(color=RED, fill_opacity=0.5)

        # 2. 配置の設定
        title.to_edge(UP) # 画面上端へ

        # 3. アニメーションの実行
        self.play(Write(title))        # 文字を書く
        self.play(DrawBorderThenFill(square)) # 枠線から塗りつぶし
        self.wait(1)

        # 4. 移動と変形 (Transform)
        self.play(
            square.animate.shift(LEFT * 2), # 左に動かしながら
            run_time=1
        )
        # 四角を円に変形させる
        self.play(ReplacementTransform(square, circle))
        self.play(circle.animate.shift(RIGHT * 4))
        
        self.wait(2)
</pre><br />オブジェクトを定義して配置し<br />アニメーション内容を書いていくことで<br />様々なアニメーションを作ることができます。<br /><br /><br /><br /><br /><span  style="font-size: 125%;">いろんなサンプルを見てみよう</span><br /><br />5つの動画サンプルを用意しました。<br /><br />1.正規分布のパラメータ変化<br />2.三角関数<br />3.フーリエ変換<br />4.ロジスティック写像<br />5.勾配降下法<br /><br /><br />どんなアニメーションを作れるかは<br />動画の方で確認してみてください。<br /><br /><br /><br /><span  style="font-size: 150%;">まとめ</span><br /><br /><br />数学や物理系の綺麗なアニメーションを作るのは<br />かなりしんどいと思います。<br /><br />このライブラリであれば、かなり綺麗な<br />アニメーションを作ることが出来るので<br />その道の動画を作りたい方は<br />試してみるのも面白いと思います。<br /><br />それでは。<br /><br /><br /><br /><br /><br /><br /><br /><br /><br />
]]>
</content:encoded>
</item>
<item rdf:about="http://www.otupy.net/archives/48227375.html">
<title>[Pythonプログラミング]南海トラフ地震はいつ来るのか</title>
<link>http://www.otupy.net/archives/48227375.html</link>
<description>南海トラフ地震はいつ起きるのか過去データから予測してみる事としました。解説動画はこちら南海トラフ地震とは駿河湾から日向灘沖にかけてのプレート境界を震源域として概ね100～150年間隔で繰り返し発生してきた大規模地震静岡県から宮崎県にかけての一部では震度７となる...</description>
<dc:creator>otupython</dc:creator>
<dc:date>2026-03-14T17:33:19+09:00</dc:date>
<dc:subject>Python</dc:subject>
<content:encoded><![CDATA[<div>南海トラフ地震はいつ起きるのか</div><div>過去データから予測してみる事としました。<br /><br />解説動画はこちら</div><br /><iframe  height="315" width="560" src="https://www.youtube.com/embed/h2uYUwYz3FU" allowfullscreen="" frameborder="0" style="vertical-align:top;" allowfullscreen></iframe><br /><br /><br /><br /><div><span  style="font-size: 150%;">南海トラフ地震とは</span><br /><br /></div><div>駿河湾から日向灘沖にかけてのプレート境界を震源域として</div><div>概ね100～150年間隔で繰り返し発生してきた大規模地震<br /><br /></div><div>静岡県から宮崎県にかけての一部では震度７となる可能性があります。<br /><br />過去の発生年<br /><br /><div>発生年<span  style="white-space: pre;">	</span>名称</div><div>1946年<span  style="white-space: pre;">	</span>昭和南海地震</div><div>1944年<span  style="white-space: pre;">	</span>昭和東南海地震</div><div>1854年<span  style="white-space: pre;">	</span>安政南海地震</div><div>1707年<span  style="white-space: pre;">	</span>宝永地震</div><div>1605年<span  style="white-space: pre;">	</span>慶長地震</div><div>1498年<span  style="white-space: pre;">	</span>明応地震</div><div>1361年<span  style="white-space: pre;">	</span>正平南海地震</div></div><br /><br /><h3  style="color: rgb(31, 31, 31); font-weight: 400; margin-bottom: 0.5em; margin-top: 0.5em; font-family: &quot;Google Sans Text&quot;, &quot;Google Sans&quot;, Noto, sans-serif;"><span  style="font-size: 150%;">地震の発生確率の計算方法</span></h3><br />最近の調査ではBPT分布というものを<br />用いた予測が基本になっています。<br /><br /><div><span  style="font-size: 150%;">BPT分布</span></div><div>（Brownian Passage Time：ブラウン通過時間）<br />地震の発生間隔をモデル化する確率分布</div><div><br />確率的に「平均的な間隔」の周辺で起こるが<br />バラつきがあるというモデル</div><div><br /><br />ポアソン分布は発生確率が常に一定（ランダム）とする一方</div><div>BPT分布は時間経過による「成熟度」を考慮したものです。<br /><br /><br /><br /><div><span  style="font-size: 150%;">BPT分布の基本式</span><br /><br /></div><div>BPT分布の確率密度関数&nbsp; 𝑓(𝑡)&nbsp; は、以下の式で表されます。</div></div><a  href="https://livedoor.blogimg.jp/otupython/imgs/2/d/2dd73f82.png" title="スクリーンショット 2026-03-14 17.25.49" target="_blank"><img  src="https://livedoor.blogimg.jp/otupython/imgs/2/d/2dd73f82-s.png" width="480" height="134" border="0" alt="スクリーンショット 2026-03-14 17.25.49" hspace="5" class="pict"></a><br /><br /><br /><br /><div><span  style="font-size: 150%;">条件付き確率の考え方</span><br /><br /></div><div>「前回の地震から&nbsp; 𝑡&nbsp; 年経過した時点で<br />今後&nbsp; Δ𝑡&nbsp; 年以内に地震が発生する確率」</div><br /><div>𝑃(𝑡,Δ𝑡)&nbsp; は、以下の式で計算します。</div><br /><a  href="https://livedoor.blogimg.jp/otupython/imgs/8/4/84165a90.png" title="スクリーンショット 2026-03-14 17.26.44" target="_blank"><img  src="https://livedoor.blogimg.jp/otupython/imgs/8/4/84165a90-s.png" width="480" height="100" border="0" alt="スクリーンショット 2026-03-14 17.26.44" hspace="5" class="pict"></a><br /><br /><br />コード上では下記が確率計算部分になります。<br /><pre  class="brush:py">prob = (f_future - f_t) / (1 - f_t)
</pre><br /><div>分子：(f_future - f_t)</div><div>「現在からXX年の期間内に地震が発生する」という確率</div><br /><div>分母：(1 - f_t)</div><div>「現在で、まだ地震が起きていない」という確率</div><br /><div>BPTモデルでは時間が経つほど&nbsp; 𝐹(𝑡)&nbsp; が大きくなるため<br />分母はどんどん小さくなっていき、確率が高まります。<br /><br /><br /></div><div><span  style="font-size: 150%;">Pythonで地震確率をシミュレーションする</span><br /><br />あらかじめことわりますが</div><div>政府予測とは異なります!!!!</div><div><br /><br />予測条件<br /><br /></div><div>平均再来間隔 (南海トラフの直近データ 1361 ~ 1946)</div><div>97.5</div><div><br />ばらつき係数 (地震調査委員会採用値)</div><div>0.24</div><div><br />前回の発生年 (昭和南海地震)</div><div>1946</div><br />今後30年間の地震発生確率を求めるコードは以下です。<br /><pre  class="brush:py">import numpy as np
from scipy.stats import norm

def bpt_cdf_30(t, mu, alpha, delta_t=30):
    """
    BPT分布に基づき、今後 delta_t 年以内の地震発生確率を計算する
    
    Parameters:
    t: 前回からの経過年数
    mu: 平均再来間隔
    alpha: ばらつき係数
    delta_t: 評価期間（デフォルトは30年）
    """
    if t &lt;= 0:
        return 0.0
    
    # 現在までの間に、既に地震が起きているはずだった累積確率
    inv_alpha_sq = 2 / (alpha**2)
    term1_t = norm.cdf((t / mu - 1) / (alpha * np.sqrt(t / mu)))
    term2_t = np.exp(inv_alpha_sq) * norm.cdf(-(t / mu + 1) / (alpha * np.sqrt(t / mu)))
    f_t = term1_t + term2_t
    
    # delta_t 年後までの間に、地震が起きる累積確率
    t_future = t + delta_t
    term1_f = norm.cdf((t_future / mu - 1) / (alpha * np.sqrt(t_future / mu)))
    term2_f = np.exp(inv_alpha_sq) * norm.cdf(-(t_future / mu + 1) / (alpha * np.sqrt(t_future / mu)))
    f_future = term1_f + term2_f
    
    if f_t &gt;= 1.0:
        return 1.0
        
    prob = (f_future - f_t) / (1 - f_t)
    return max(0.0, min(prob, 1.0))

mu = 97.5       # 平均再来間隔 (南海トラフの直近データ 1361 ~ 1946)
alpha = 0.24    # ばらつき係数 (地震調査委員会採用値)
last_event = 1946  # 前回の発生年 (昭和南海地震)
target_year = 2026
t = target_year - last_event

# 30年分を予測
for delta_t in range(1, 31):
  prob = bpt_cdf_30(t, mu, alpha, delta_t)
  print(f"今後 {delta_t} 年以内の発生確率: {prob:.2%}")
</pre><br />今後30年間の発生確率は<br />ぜひ動画を見てみてください。<br /><br /><br /><br /><br /><div><span  style="font-size: 150%;">まとめ</span><br /><br />地震の発生確率は確率分布をもとに<br />予測が行われています。<br /><br />政府予測では</div><div>今後、30年の間に 60％～90％程度以上の確率で</div><div>南海トラフ地震来るという予測です<br /><br /></div><div>絶対は無いけど、明日来るかもしれない</div><div>いつ来ても良いように備えておきましょう!!!</div><br />それでは<br />&nbsp;
]]>
</content:encoded>
</item>
<item rdf:about="http://www.otupy.net/archives/48205813.html">
<title>[Pythonプログラミング]DuckDBで簡単SQLデータ分析</title>
<link>http://www.otupy.net/archives/48205813.html</link>
<description>今回はDuckDBを用いた簡単SQLデータ分析についてです解説動画はこちらDuckDBデータ分析したいけどSQLならわかるんだけどPython良く分からないなーそんな時はDuckDB使えばいいじゃない！！ということでDuckDBのご紹介です。Python上でSQLでデータ取得できるライブラリでDataFr...</description>
<dc:creator>otupython</dc:creator>
<dc:date>2026-03-07T17:22:50+09:00</dc:date>
<dc:subject>プログラミング</dc:subject>
<content:encoded><![CDATA[今回はDuckDBを用いた<br />簡単SQLデータ分析についてです<br /><br />解説動画はこちら<br /><iframe  height="315" width="560" src="https://www.youtube.com/embed/R64yVL7j9VA" allowfullscreen="" frameborder="0" style="vertical-align:top;" allowfullscreen></iframe><br /><br /><br /><div><span  style="font-size: 150%;">DuckDB</span></div><br /><div>データ分析したいけどSQLならわかるんだけど</div><div>Python良く分からないなー</div><div><br />そんな時はDuckDB使えばいいじゃない！！<br /><br />ということで<br />DuckDBのご紹介です。<br /><br /></div><div>Python上でSQLでデータ取得できるライブラリで</div><div>DataFrameをそのままSQLテーブルとして扱えます。<br /><br /></div><div>pandasの複雑なメソッドを覚えなくても<br />SQL操作で任意のデータが抽出できるものです。</div><div>pandasも加えると更に深掘りも出来てお得です。<br /><br /><br />早速使い方を見ていきましょう。<br /><br /><br /><span  style="font-size: 150%;">インストール</span><br /><br /><div>Google Colabでは<br />インストール済みなので不要です。</div><br /><div>ローカルなどでインストールしていない人は<br />下記コマンドを実行しておいてください。<br /><pre  class="brush:py">pip install duckdb
</pre><br /></div><br /></div><div><span  style="font-size: 125%;">ライブラリの呼び出し</span></div><br /><div>これだけです。<br /><pre  class="brush:py">import duckdb
</pre><br /><br />操作の基本<br /><pre  class="brush:py"># 実行結果を表示
duckdb.sql("SQL文").show()

# 実行結果を変数に格納
データフレーム変数 = duckdb.sql("SQL文").df()
</pre><br />データフレームを作ってSQL文を投げてみます<br /><pre  class="brush:py">import pandas as pd

df = pd.DataFrame({
    "a":[1,2,3],
    "b":[10,20,30]
})

sql = "SELECT * FROM df WHERE a &gt; 1"

result_df = duckdb.sql(sql).df()
result_df
</pre><br /><table  border="1" class="dataframe" style="border-collapse: collapse; border-spacing: 0px; border: none; table-layout: fixed; color: rgb(31, 31, 31); font-family: &quot;Google Sans Text&quot;, &quot;Google Sans&quot;, Noto, sans-serif; font-size: 14px;"><thead  style="border-bottom: 1px solid rgb(196, 199, 197); font-family: monospace; text-align: right;"><tr  style="border: none; padding: 0.5em;"><th  style="border: none; padding: 0.5em; text-align: right;">a</th><th  style="border: none; padding: 0.5em; text-align: right;">b</th></tr></thead><tbody><tr  style="border: none; padding: 0.5em; background: none 0% 0% / auto repeat scroll padding-box border-box rgb(242, 242, 242);"><th  style="border: none; padding: 0.5em; vertical-align: middle;">0</th><td  style="border: none; padding: 0.5em; text-align: right;">2</td><td  style="border: none; padding: 0.5em; text-align: right;">20</td></tr><tr  style="border: none; padding: 0.5em;"><th  style="border: none; padding: 0.5em; vertical-align: middle;">1</th><td  style="border: none; padding: 0.5em; text-align: right;">3</td><td  style="border: none; padding: 0.5em; text-align: right;">30</td></tr></tbody></table><br />DuckDBではデータフレームや<br />ファイルに直接SQL文のクエリを実行し<br />データ抽出が行えます。<br /><br /><br /><span  style="font-size: 125%;">SQL分をファイルから読み込みする</span><br /><pre  class="brush:py">sql = open("ファイルパス").read()
df = duckdb.sql(sql).df()
</pre><br /><br /><div><span  style="font-size: 125%;">ファイルを直接クエリする</span></div><br /><pre  class="brush:py">sql = open("ファイルパス").read()
df = duckdb.sql(sql).df()
</pre>Google Colabなどでもファイルを置いておけば参照できます。<br /><br /><br /><br /><span  style="font-size: 150%;">サンプルデータで簡易分析</span><br /><br />sklearnサンプルデータを用いて<br />DuckDBでSQL分析してみましょう。<br /><br />今回用いるデータは<br />「California Housing Dataset」<br /><br />カリフォルニアの<br />地域ごとの住宅価格などのデータです。<br />下記コードで読み込みできます。<br /><pre  class="brush:py">import duckdb
import pandas as pd
from sklearn.datasets import fetch_california_housing

# データロード
data = fetch_california_housing(as_frame=True)

df = data.frame

# DuckDBに接続
con = duckdb.connect()

# DataFrameを登録
con.register("housing", df)
</pre><br />データの準備が整ったら<br />DuckDBでSQLを実行してみましょう。<br /><br />1.平均住宅価格<br /><pre  class="brush:py">sql = """
SELECT
    AVG(MedHouseVal) as avg_price
FROM housing
"""

print(con.sql(sql).df())
</pre><br />2.住宅価格ランキング<br /><pre  class="brush:py">sql = """
SELECT
    MedHouseVal
FROM housing
GROUP BY MedHouseVal
ORDER BY MedHouseVal DESC
LIMIT 10
"""

print(con.sql(sql).df())
</pre><br />3.地域ごとの住宅価格<br /><pre  class="brush:py">sql = """
SELECT
    ROUND(Latitude,1) as lat,
    ROUND(Longitude,1) as lon,
    AVG(MedHouseVal) as avg_price,
    COUNT(*) as houses
FROM housing
GROUP BY lat, lon
ORDER BY avg_price DESC, houses DESC
LIMIT 15
"""

print(con.sql(sql).df())
</pre>
<br />4.収入と住宅価格<br /><pre  class="brush:py">sql = """
SELECT
    CASE
        WHEN MedInc &lt; 2 THEN 'low'
        WHEN MedInc &lt; 5 THEN 'middle'
        ELSE 'high'
    END as income_level,
    AVG(MedHouseVal) as avg_price,
    COUNT(*) as cnt
FROM housing
GROUP BY income_level
ORDER BY avg_price DESC
"""

print(con.sql(sql).df())
</pre><br />5.家の広さと価格<br /><pre  class="brush:py">sql = """
SELECT
    ROUND(AveRooms,0) as rooms,
    AVG(MedHouseVal) as price,
    COUNT(*) as n
FROM housing
GROUP BY rooms
HAVING n &gt; 50
ORDER BY rooms
"""

print(con.sql(sql).df())
</pre><br /><br /><div><span  style="font-size: 125%;">応用編</span></div><br />海沿い住宅は高いのかどうか<br /><br /><div>カリフォルニアは 西側が海なので</div><div>経度(Longitude) で判定</div><br /><br /><pre  class="brush:py">sql = """
SELECT
    CASE
        WHEN Longitude &lt; -121 THEN 'coastal'
        ELSE 'inland'
    END AS location_type,
    AVG(MedHouseVal) AS avg_house_price,
    COUNT(*) AS houses
FROM housing
GROUP BY location_type
"""

result = con.sql(sql).df()

print("海沿い住宅(coastal) vs 内陸住宅(inland)")
print(result)
</pre><br />結果はコードを試すか<br />動画の方をご覧ください<br /><br /><br /><br /><br /><br /><span  style="font-size: 150%;">まとめ</span><br /><br /><br /><div>DuckDBを用いるとSQLを使ったデータ分析が<br />簡単に行えます。<br /><br /></div><div>Pythonのコードに慣れていなくても</div><div>直接ファイルにSQLを実行して分析結果を得られます。</div><div><br />複雑な集計もSQLを書ければ出来ちゃうので</div><div>データアナリストでなくても簡単に分析できちゃいます。<br /><br />手元にデータが有るけどデータベース作れない<br />SQLは分かるけどpython分からない人向け<br />超お手軽ライブラリなので、おすすめです<br /><br />ぜひ試してみてください<br />それでは。<br /><br /><br /></div><br /><br /></div><br />&nbsp;
]]>
</content:encoded>
</item>
<item rdf:about="http://www.otupy.net/archives/48162963.html">
<title>[Pythonプログラミング]FastAPI × htmx で作るプロトタイプを爆速実装する方法</title>
<link>http://www.otupy.net/archives/48162963.html</link>
<description>今回はFastAPI × htmx で作るプロトタイプを爆速実装する方法についてです。解説動画はこちら FastAPI × htmx昨今のPython界隈は streamlit というライブラリのおかげでフロントエンドもまとめて作ることができる様になりました。そのおかげで、似たような見た目ばかりに...</description>
<dc:creator>otupython</dc:creator>
<dc:date>2026-02-21T17:43:15+09:00</dc:date>
<dc:subject>プログラミング</dc:subject>
<content:encoded><![CDATA[今回は<br />FastAPI × htmx で作るプロトタイプを爆速実装する方法<br />についてです。<br /><br /><br />解説動画はこちら<br /><iframe  height="315" width="560" src="https://www.youtube.com/embed/rE9k1NJCOMw" allowfullscreen="" frameborder="0" style="vertical-align:top;" allowfullscreen></iframe><br /><br /><br /><br /><span  style="font-size: 150%;">&nbsp;FastAPI × htmx</span><br /><br />昨今のPython界隈は streamlit というライブラリのおかげで<br />フロントエンドもまとめて作ることができる様になりました。<br /><br />そのおかげで、似たような見た目ばかりになる<div>streamlit臭のするデザインのモックばかり<br />という哀しい現象が起きてきています。<br /><br />なので、こんな状況を打破すべく<br />&nbsp;- デザイン部分は自由に作り込める</div><div>&nbsp;- フロントエンド（React/Vue）の学習コストが高すぎて、モック作りが進まない</div><div>&nbsp;- FastAPI(堅牢なバックエンド) + htmx(HTML だけで Ajax)というシンプル構成</div><br />という&nbsp;FastAPI + htmx の組み合わせの方法をお伝えします。<br /><br /><br /><div><span  style="font-size: 150%;">FastAPI とは何か</span></div><br /><div>爆速で動く、現代的な『注文受け付け窓口』</div><div>Python言語で作られたWEBフレームワークです。</div><br /><div>プログラムの実行速度が非常に速く<br />開発者がコードを書くスピードも速くなるように設計されており<br /><br /></div><div>仕様書（APIドキュメント）を自動で作成</div><div>型（データ）のチェックなども行ってくれます。<br /><br /><br /><div><span  style="font-size: 150%;">htmx とは何か</span></div><br /><div>HTMLを『魔法の言葉』に変える道具</div><div>通常、Webページの一部を書き換えるには<br />JavaScriptをたくさん書く必要があります。<br /><br /></div><div>htmxだと「HTMLを数文字書き足すだけ」で実現でき</div><div>JavaScriptの部分をHTMLの属性だけで指示できるます。<br /><br /></div><div>学習コストが劇的に低い(HTMLが分かるなら)</div></div>ので初学者でも取り組みが楽です。<br /><br /><br />なので<br />この組み合わせが事業モックに最適です。<br /><br /><div>フロントとバックエンド、2つの学習コストが低い</div><div>シンプルでサクサク動くし、修正が簡単<br /><br /></div><div>モックとして作った後も<br />そのまま本番サービス転用も可能です。</div><br /><br /><br /><span  style="font-size: 150%;">環境構築と基本設定</span><br /><br />Python側のインストール<br /><pre  class="brush:py">pip install fastapi uvicorn jinja2 python-multipart
</pre><br /><br />FASTAPIの実行方法<br />main.py のあるディレクトリで<br /><pre  class="brush:py">uvicorn main:app --reload</pre><br /><div>WEBブラウザー側で http://127.0.0.1:8000/ <br />にアクセスするとFASTAPIの画面が見れます。<br /><br /><br /><br /></div><span  style="font-size: 150%;">デモプロジェクトの概要</span><br /><br /><br />デモプロジェクトのディレクトリ構成<br /><br /><div>├── main.py</div><div>└── templates/</div><div>&nbsp; &nbsp; ├── index.html&nbsp; &nbsp; &nbsp; &nbsp; (ベースレイアウト)</div><div>&nbsp; &nbsp; ├── customer_list.html (顧客一覧)</div><div>&nbsp; &nbsp; ├── customer_detail.html (顧客詳細)</div><div>&nbsp; &nbsp; ├── stock_list.html&nbsp; &nbsp; (在庫一覧)</div><div>&nbsp; &nbsp; ├── stock_detail.html&nbsp; (在庫詳細)</div><div>&nbsp; &nbsp; └── chat.html&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (AIチャット)</div><br /><br />こんな内容のものを作ることができます。<br /><a  target="_blank" title="スクリーンショット 2026-02-21 17.28.21" href="https://livedoor.blogimg.jp/otupython/imgs/b/d/bd6ee194.png"><img  class="pict" hspace="5" alt="スクリーンショット 2026-02-21 17.28.21" border="0" height="167" width="480" src="https://livedoor.blogimg.jp/otupython/imgs/b/d/bd6ee194-s.png"></a><br /><a  target="_blank" title="スクリーンショット 2026-02-21 17.28.28" href="https://livedoor.blogimg.jp/otupython/imgs/9/5/95b4c24e.png"><img  class="pict" hspace="5" alt="スクリーンショット 2026-02-21 17.28.28" border="0" height="182" width="480" src="https://livedoor.blogimg.jp/otupython/imgs/9/5/95b4c24e-s.png"></a><br /><a  target="_blank" title="スクリーンショット 2026-02-21 17.28.34" href="https://livedoor.blogimg.jp/otupython/imgs/f/9/f9d12ed3.png"><img  class="pict" hspace="5" alt="スクリーンショット 2026-02-21 17.28.34" border="0" height="290" width="480" src="https://livedoor.blogimg.jp/otupython/imgs/f/9/f9d12ed3-s.png"></a><br /><br /><br /><br /><br />main.py のコード<br /><br />FAST API のコードはこんな感じになっています。<br /><pre  class="brush:py">from fastapi import FastAPI, Request, Form
from fastapi.responses import HTMLResponse
from fastapi.templating import Jinja2Templates
from fastapi.staticfiles import StaticFiles
from datetime import datetime

app = FastAPI()
templates = Jinja2Templates(directory="templates")

# --- ダミーデータ ---
CUSTOMERS = {
    "C001": {"id": "C001", "name": "山田 太郎", "birth": "1985/05/20", "gender": "男性", "address": "東京都渋谷区...", "rank": "S", "items": [{"name": "ルンバ", "qty": 1, "price": 50000}]},
    "C002": {"id": "C002", "name": "佐藤 花子", "birth": "1992/11/02", "gender": "女性", "address": "大阪府大阪市...", "rank": "A", "items": [{"name": "化粧水", "qty": 2, "price": 4000}]},
    # ...他3件（実装上は同様に定義）
}

STOCKS = {
    "S001": {"id": "S001", "name": "ロキソニンS", "category": "解熱鎮痛剤", "count": 150, "desc": "第1類医薬品。速効性に優れています。"},
    "S002": {"id": "S002", "name": "アレグラFX", "category": "鼻炎薬", "count": 45, "desc": "眠くなりにくいアレルギー専用鼻炎薬。"},
}

def calc_age(birth_str):
    birth_date = datetime.strptime(birth_str, "%Y/%m/%d")
    today = datetime.today()
    return today.year - birth_date.year - ((today.month, today.day) &lt; (birth_date.month, birth_date.day))

# --- Routes ---
@app.get("/", response_class=HTMLResponse)
async def index(request: Request):
    return templates.TemplateResponse("index.html", {"request": request})

# 1. 顧客管理
@app.get("/customers", response_class=HTMLResponse)
async def list_customers(request: Request):
    data = []
    for c in CUSTOMERS.values():
        data.append({**c, "age": calc_age(c['birth']), "birth_month": c['birth'][:7]})
    return templates.TemplateResponse("customer_list.html", {"request": request, "customers": data})

@app.get("/customers/{cid}", response_class=HTMLResponse)
async def detail_customer(request: Request, cid: str):
    c = CUSTOMERS.get(cid)
    return templates.TemplateResponse("customer_detail.html", {"request": request, "customer": c, "age": calc_age(c['birth'])})

# 2. 在庫チェック
@app.get("/stocks", response_class=HTMLResponse)
async def list_stocks(request: Request):
    return templates.TemplateResponse("stock_list.html", {"request": request, "stocks": STOCKS.values()})

@app.get("/stocks/{sid}", response_class=HTMLResponse)
async def detail_stock(request: Request, sid: str):
    return templates.TemplateResponse("stock_detail.html", {"request": request, "stock": STOCKS.get(sid)})

# 3. AIチャット
@app.get("/chat", response_class=HTMLResponse)
async def chat_page(request: Request):
    return templates.TemplateResponse("chat.html", {"request": request})

@app.post("/chat/send", response_class=HTMLResponse)
async def chat_send(request: Request, message: str = Form(...)):
    # 簡易的なAIレスポンスのシミュレーション
    ai_response = f"「{message}」について承知いたしました。AIとしての回答をここに表示します。"
    return f"""ここは省略しています"""
</pre><br />index.htmlなどは<br />AIエージェントを使って作ってみてください<br /><br /><br /><br /><br /><br /><span  style="font-size: 150%;">まとめ</span><br /><br /><br /><div>FAST API + htmx を用いると爆速でモック開発ができる</div><div>こちらは必要最低限の知識を学ぶだけで済む</div><div>デザイン部分は自由に作り込めるので好きなCSSを勉強しよう</div><br /><div>足りない部分はAIエージェント使ってください</div><div>こちらは作りたいものを指示するだけ</div><div>本番作りもAIエージェントで爆速開発できます<br /><br />PS<br />最近はこれでプロトタイプ開発していたりします。<br />AIエージェントも使いこなせると<br />爆速で開発できる様にできますよ<br /><br />それでは。<br /><br /></div>&nbsp;
]]>
</content:encoded>
</item>
<item rdf:about="http://www.otupy.net/archives/48139010.html">
<title>バイブコーディングのコツ</title>
<link>http://www.otupy.net/archives/48139010.html</link>
<description>今回はバイブコーディングをうまく行かせるためのコツについてです。解説動画はこちらバイブコーディングのコツ昨今ではもう当たり前になってきているバイブコーディングこれをうまく活かせるためのコツについてお伝えします。ポイントは3つだけ1.マークダウン形式で指示する...</description>
<dc:creator>otupython</dc:creator>
<dc:date>2026-02-14T17:40:14+09:00</dc:date>
<dc:subject>プログラミング</dc:subject>
<content:encoded><![CDATA[今回はバイブコーディングを<br />うまく行かせるためのコツについてです。<br /><br />解説動画はこちら<br /><iframe  height="315" width="560" src="https://www.youtube.com/embed/yqJgEQNf7SE" allowfullscreen="" frameborder="0" style="vertical-align:top;" allowfullscreen></iframe><br /><br /><br /><br /><span  style="font-size: 150%;">バイブコーディングのコツ</span><br /><br /><br />昨今ではもう当たり前になってきている<br />バイブコーディング<br /><br />これをうまく活かせるための<br />コツについてお伝えします。<br /><br /><br />ポイントは3つだけ<br /><br />1.マークダウン形式で指示する<br /><br />2.ロールを与える<br /><br />3.できるだけ具体的に指示する<br /><br />これだけ守れたら十分です<br /><br />それ以外の説明や細かい所は<br />動画の方を見ていただければと思います。<br /><br /><br /><br /><span  style="font-size: 150%;">ゲーム作成プロンプト</span><br /><br />この内容に、追加で仕様を加えるなどで<br />改変することができると思います。<br /><pre  class="brush:py"># 依頼：HTML Canvasを使用した「掘削アクションパズル」の作成

以下の仕様に基づき、シングルファイルのHTML（HTML/CSS/JS一体型）でゲームを作成してください。

## 1. ゲーム概要
- タイトル：簡易版ドリラー
- プレイヤーは下方向に向かってブロックを掘り進み、スコアと深さを競う。
- 「酸素（AIR）」の概念があり、時間経過で減少する。

## 2. コアメカニクス
- **移動と掘削**: 
    - 矢印キーで移動。
    - 隣接する（上下左右）ブロックを、移動キー(左、下、右)で破壊。
    - 1ブロック下に進むごとに深さを +1する
    - 破壊できたらその方向に進む
- **ブロックの挙動**:
    - ブロックの種類は4種類
    - 青色の土ブロック : 1アクションで破壊可能、破壊するのに酸素ゲージを1消費する
    - 茶色の土ブロック : 2アクションで破壊可能、破壊するのに酸素ゲージを2消費する
    - 灰色の岩ブロック : 3アクションで破壊可能、破壊するのに酸素ゲージを5消費する
    - 銀色のメタルブロック : 破壊不能、移動アクション毎に酸素ゲージを2消費する
- **リソース管理**:
    - 酸素ゲージは最大100。毎秒1ずつ減少。
    - 特定のブロック（エアーカプセル）を取得すると酸素が15回復。
    - 特定のブロックの破壊でも酸素ゲージを消費する
    - 酸素ブロックはおよそ、30メートルに1つの割合で出現する
- **ゲーム管理**:
    - 画面読み込みと同時にゲーム開始
    - 酸素ゲージ0でゲームオーバー
    - スペースキー押下で再ゲームスタート

## 3. 画面構成
- 画面の上部と下部の2部構成
- 画面上部はスコアなどの表示ゾーン
- Canvasサイズ400x100
- 画面上部に左から「DEPTH（深さ）スコア」「AIR（残り酸素）ゲージ」を表示。
- DEPTHスコアの表示は画面左上に固定し、数値4桁で0埋めする
- AIRゲージは画面上部の中央に長めに固定
- AIRゲージ全体は白枠組みで、残り酸素を黄色で表現し右から左に向かって減るようにする
- AIRゲージの右側に残り酸素を数値で表示(MAX100で3桁0埋めする)
- 画面下部はブロックゾーン
- Canvasサイズ: 400x600（縦長）
- ブロックサイズ: 40x40のグリッド
- 掘り進めるごとに、うまく調整してスクロールするようにする
- 深さ10m毎にブロックキャンバスの左外側にその深さを数値で表示させる

## 4. ビジュアル・操作性
- ブロックの色は4色（青、茶、灰、銀）、それぞれ、四角で表現し、枠は白くする
- エアーカプセルは桃色の簡易的な丸型図形とする
- キャラクターは黒色の簡易的な下向きの三角形でOK。
- 操作：
    - Left/Right：移動
    - Down：下のブロックを掘る

## 5. 実装のステップ
1. Canvasのセットアップとゲームループ（requestAnimationFrame）の作成。
2. ブロック配置データの生成（配列管理）。
3. プレイヤーの移動と掘削処理。
4. ブロックの消滅ロジックの実装。
5. 酸素減少とゲームオーバー判定の実装。

まずは、これらを網羅した動くコードを出力してください。
</pre><br /><br />これをLLMに直接放り投げれば<br />HTMLでJSを用いたゲームを作ってもらえると思います。<br /><br />是非コピペしてみてください<br /><br />それでは。<br /><br /><br /><br /><br />&nbsp;
]]>
</content:encoded>
</item>
<item rdf:about="http://www.otupy.net/archives/41090674.html">
<title>[プログラミング講座] 1時間で学べるPythonプログラミング</title>
<link>http://www.otupy.net/archives/41090674.html</link>
<description>プログラミング未経験の方のためのプログラミング学習講座を作成しましたその名も「1時間で学べるPythonプログラミング」講義動画はこちらこの講座は初学者の方が短時間でPython言語を学ぶことのできるプログラミング学習用の講座ですプログラミングが分からないな...</description>
<dc:creator>otupython</dc:creator>
<dc:date>2026-02-01T16:32:06+09:00</dc:date>
<dc:subject>Python</dc:subject>
<content:encoded><![CDATA[プログラミング未経験の方のための<br />プログラミング学習講座を作成しました<br /><br />その名も<br />「1時間で学べるPythonプログラミング」<br /><br /><br />講義動画はこちら<br /><br /><iframe  height="315" width="560" src="https://www.youtube.com/embed/HXcIKXu6bE8" allowfullscreen="" frameborder="0" style="vertical-align:top;" allowfullscreen></iframe><br /><br /><br /><div>この講座は初学者の方が</div><div>短時間でPython言語を学ぶことのできる</div><div>プログラミング学習用の講座です</div><br /><div>プログラミングが分からないない方は</div><div>Python言語を通じて<br />プログラミングの基礎を学習できます</div><br /><div>講座は動画に加えてGoogle Colabを用いて</div><div>手元でコードを動かすことのできます</div><div>コードがどう動くのかを確認をしながら</div><div>進めていってください</div><br /><div>資料はここ：<br /><a  title="" target="_blank" href="https://colab.research.google.com/drive/1o-JOLb-9W15BJnkGR-w5-r6b3ZgjMSdC?usp=sharing">Google Colabの資料</a></div><br /><br /><div>00:00 1.はじめに</div><div>02:13 2.導入方法</div><div>02:55 3.GoogleColaboratoryの操作方法</div><div>06:19 4.Pythonの計算の基礎</div><div>27:27 5.Pythonの制御文</div><div>42:14 6.Pythonのクラス</div><div>49:11 7.Pythonのその他構文</div><div>64:30 8.まとめ<br /><br /></div><h1  style="box-sizing: border-box; margin: 0.538em 0px 0px; font-family: &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; line-height: 1; text-size-adjust: auto;" id="乙py式５時間で学ぶプログラミング基礎(python編)"><span  style="font-size: 100%;">なおPythonチートシートを作成しています。</span><br /><br /><span  style="font-size: 100%;">コーディングに迷った際に役に立ち</span><br /><br /><span  style="font-size: 100%;">WEB検索する時間を無くして</span><br /><br /><span  style="font-size: 100%;">作業時間を効率化できます。<br /></span><br />note<br /><a  href="https://note.mu/otupy/n/n1bedb9f36e54" target="_blank"><span  style="font-size: 200%;">Pythonチートシート</span></a></h1><br />&nbsp;
]]>
</content:encoded>
</item>
<item rdf:about="http://www.otupy.net/archives/48052118.html">
<title>Xのフィードアルゴリズム2026</title>
<link>http://www.otupy.net/archives/48052118.html</link>
<description>今回は最近公開されたXのフィードアルゴリズムについてです解説動画はこちらXのフィード・アルゴリズムの仕組みについてXのアルゴリズムコードはこちらになります。xaiシステムの4つの主要コンポーネントXのフィードアルゴリズムは大きく4つのコンポーネントで構成されていま...</description>
<dc:creator>otupython</dc:creator>
<dc:date>2026-01-24T18:17:35+09:00</dc:date>
<dc:subject>Python</dc:subject>
<content:encoded><![CDATA[今回は最近公開された<br />Xのフィードアルゴリズムについてです<br /><br />解説動画はこちら<br /><iframe  height="315" width="560" src="https://www.youtube.com/embed/RKP7TUgMPLs" allowfullscreen="" frameborder="0" style="vertical-align:top;" allowfullscreen></iframe><br /><br /><br /><br /><br /><span  style="font-size: 150%;">Xのフィード・アルゴリズムの仕組みについて</span><br /><br />Xのアルゴリズムコードはこちらになります。<br /><br /><a  href="https://github.com/xai-org/x-algorithm" target="_blank" title="">xai</a><br /><br /><br /><span  style="font-size: 150%;"><br />システムの4つの主要コンポーネント</span><br /><br /><br />Xのフィードアルゴリズムは<br />大きく4つのコンポーネントで構成されています。<br /><br /><a  href="https://livedoor.blogimg.jp/otupython/imgs/e/2/e28e8c40.png" title="4components" target="_blank"><img  src="https://livedoor.blogimg.jp/otupython/imgs/e/2/e28e8c40-s.png" width="480" height="249" border="0" alt="4components" hspace="5" class="pict"></a><br /><br /><br /><br />1. Home Mixer: <br />全体の司令塔（オーケストレーション層）です。<br /><div><br />候補の抽出からランク付け、フィルタリングまでの全工程を管理します。</div>パイプラインは以下のステージで構成されています:<br /><br /><div>&nbsp; &nbsp; 1.Query Hydration - ユーザーのエンゲージメント履歴とメタデータを取得</div><div>&nbsp; &nbsp; 2.Candidate Sources - ThunderとPhoenixから候補を取得</div><div>&nbsp; &nbsp; 3.Hydration - 候補に追加データを付与</div><div>&nbsp; &nbsp; 4.Pre-Scoring Filters - 不適格な投稿を除外</div><div>&nbsp; &nbsp; 重複、古い投稿、自分の投稿、ブロック/ミュートしたアカウント、ミュートキーワードなど</div><div>&nbsp; &nbsp; 5.Scoring - 複数のスコアラーを順次適用</div><div>&nbsp; &nbsp; &nbsp; Phoenix Scorer (ML予測)</div><div>&nbsp; &nbsp; &nbsp; Weighted Scorer (予測の重み付け結合)</div><div>&nbsp; &nbsp; &nbsp; Author Diversity Scorer (多様性のための減衰)</div><div>&nbsp; &nbsp; &nbsp; OON Scorer (Out-of-Network調整)</div><div>&nbsp; &nbsp; 6.Selection - スコアでソートし、上位K件を選択</div><div>&nbsp; &nbsp; 7.Post-Selection Filters - 最終検証 (削除済み/スパム/暴力的コンテンツなど)</div><div>&nbsp; &nbsp; 8.Side Effects - キャッシュとログ記録</div><br /><br />2.&nbsp;Thunder:<br />フォロー中ユーザーの投稿をリアルタイムで追跡するメモリ内ストアです。<br /><br />ミリ秒単位の高速な読み込みを可能にします。<br /><br /><div>主要機能:</div><div>&nbsp; &nbsp; 1.Kafkaからのリアルタイム取り込み - 投稿の作成/削除イベントを消費</div><div>&nbsp; &nbsp; 2.ユーザー別ストア管理 - オリジナル投稿、リプライ/リツイート、動画投稿を分類</div><div>&nbsp; &nbsp; 3.サブミリ秒ルックアップ - 外部データベースにアクセスせずに高速検索</div><div>&nbsp; &nbsp; 4.自動トリミング - 保持期間を超えた古い投稿を自動削除</div><br /><div>パフォーマンス最適化:</div><div>&nbsp; &nbsp; 1.タイムアウト機能 (デフォルト設定可能)</div><div>&nbsp; &nbsp; 2.ユーザーあたりの投稿数制限</div><div>&nbsp; &nbsp; 3.メモリ効率化のための自動容量調整</div><br /><br />3.&nbsp;Phoenix:<br />機械学習（ML）を担当する心臓部です。<br /><br /><div>検索: フォロー外から好みに合う投稿を見つけ出します。</div><div>ランキング: ユーザーがその投稿に反応（いいねやリプライなど）する確率を予測します。</div><br />・アルゴリズムの詳細<br /><div><br />2つのステップ</div><br /><div>1. Retrieval（Retrieval段階）: <br />数億のツイートから、2タワーモデル（Two-Tower Model）を用いて<br />「関連がありそうな数千件」をミリ秒単位で抽出します。</div><br /><div>2. Ranking（ランキング段階）: <br />抽出された数千件に対し、トランスフォーマーモデルを用いて<br />いいねやリポストなどの「具体的なエンゲージメント確率」を<br />詳細に予測・採点します。</div><br /><br /><div>Retrieval: Two-Tower Model (2タワーモデル)</div><div><div>&nbsp; &nbsp;1. User Tower（ユーザー側）:&nbsp;</div><div>&nbsp; &nbsp;ユーザーの属性（User Hashes）と、過去のエンゲージメント履歴（History）を</div><div>&nbsp; &nbsp;トランスフォーマーで処理し、ユーザーの「現在の興味」を</div><div>&nbsp; &nbsp;1つの数値ベクトル（User Representation）に凝縮します。</div><br /><div>&nbsp; &nbsp;2. Candidate Tower（ツイート側）:&nbsp;</div><div>&nbsp; &nbsp;ツイート内容や投稿者情報を同様にベクトル化（Candidate Representation）します。</div></div><br />近さの計算（ドット積）<br /><div>&nbsp; &nbsp;「近さ」の採点は、ユーザーベクトルと<br />&nbsp; &nbsp;ツイートベクトルの**ドット積（内積）**で行われます。<br /><br /></div><div>&nbsp; &nbsp;ベクトル同士の向きが近い（興味が一致する）ほどスコアが高くなります。</div><div>&nbsp; &nbsp;全てのツイートが事前にベクトル化されているため<br />&nbsp; &nbsp;数億件の中から瞬時に上位K件を取得可能です。</div><br /><br />Multi-Action Prediction (複数アクション予測)<br /><div>&nbsp; &nbsp;P(favorite)&nbsp; &nbsp; &nbsp; - いいね</div><div>&nbsp; &nbsp;P(reply)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;- リプライ</div><div>&nbsp; &nbsp;P(repost)&nbsp; &nbsp; &nbsp; &nbsp; - リツイート</div><div>&nbsp; &nbsp;P(quote)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;- 引用ツイート</div><div>&nbsp; &nbsp;P(click)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;- クリック</div><div>&nbsp; &nbsp;P(profile_click) - プロフィールクリック</div><div>&nbsp; &nbsp;P(video_view)&nbsp; &nbsp; - 動画視聴</div><div>&nbsp; &nbsp;P(share)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;- シェア</div><div>&nbsp; &nbsp;P(dwell)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;- 滞在時間</div><div>&nbsp; &nbsp;P(follow_author) - フォロー</div><div>&nbsp; &nbsp;P(not_interested) - 興味なし (負の重み)</div><div>&nbsp; &nbsp;P(block_author)&nbsp; - ブロック (負の重み)</div><div>&nbsp; &nbsp;P(mute_author)&nbsp; &nbsp;- ミュート (負の重み)</div><div>&nbsp; &nbsp;P(report)&nbsp; &nbsp; &nbsp; &nbsp; - 報告 (負の重み)</div><br /><br />最終スコア計算:<br /><br /><div>&nbsp; &nbsp;Final Score = Σ (weight_i × P(action_i))</div><div><br />ポジティブなアクションは正の重み、ネガティブなアクションは負の重みを持ちます。</div><br /><br />4.Candidate Pipeline:<br />推薦システムを構築するための再利用可能なフレームワークです。<br /><div>&nbsp; &nbsp;Source<span  style="white-space: pre;">	</span>データソースから候補を取得</div><div>&nbsp; &nbsp;Hydrator<span  style="white-space: pre;">	</span>候補に追加特徴を付与</div><div>&nbsp; &nbsp;Filter<span  style="white-space: pre;">	</span>表示すべきでない候補を除外</div><div>&nbsp; &nbsp;Scorer<span  style="white-space: pre;">	</span>ランキング用のスコアを計算</div><div>&nbsp; &nbsp;Selector<span  style="white-space: pre;">	</span>上位候補をソート・選択</div><div>&nbsp; &nbsp;SideEffect<span  style="white-space: pre;">	</span>非同期サイドエフェクト実行 (キャッシュ、ログ)</div><div>&nbsp; &nbsp;QueryHydrator<span  style="white-space: pre;">	</span>クエリコンテキストを準備</div><br /><br /><br /><br /><span  style="font-size: 150%;">おすすめが表示されるまでの流れ</span><br /><br /><br />フィードが生成されるまでには、以下のステップを踏みます。<br /><a  href="https://livedoor.blogimg.jp/otupython/imgs/1/0/10f132f9.png" title="flow" target="_blank"><img  src="https://livedoor.blogimg.jp/otupython/imgs/1/0/10f132f9-s.png" width="480" height="251" border="0" alt="flow" hspace="5" class="pict"></a><br /><br /><br /><div><div>1. データの準備 (Hydration): ユーザーの過去のエンゲージメント履歴や</div><div>フォローリストを読み込みます。</div><br /><div>2. 候補の抽出: 「Thunder（フォロー内）」と「Phoenix（フォロー外）」の</div><div>両方から候補となる投稿を集めます。</div><div>&nbsp; &nbsp;</div><div>3. フィルタリング（前処理）: 重複した投稿、古すぎる投稿</div><div>自分がブロックしている相手の投稿、既に見た投稿などを除外します。</div><br /><div>4. スコアリング（ランク付け）:</div><div>&nbsp;Grokベースのモデルが「いいね」「リプライ」「リポスト」</div><div>&nbsp;「クリック」などの発生確率を個別に予測します。</div><div>&nbsp;それらを重み付けして最終スコアを算出します。</div><div>&nbsp;特定の著者ばかりに偏らないよう「著者多様性スコア」で調整をかけます。</div><br /><div>5. 最終選定: スコアの高い順に並べ替え、最終的な表示候補を選び出します。</div><br /><div>6. フィルタリング（後処理）: 削除済み、スパム、暴力的なコンテンツなどが</div><div>混じっていないか最終チェックを行います。</div></div><br /><br /><span  style="font-size: 150%;">おすすめに表示されやすくなるポイント</span><br /><br /><div>ポジティブエンゲージメント<br />以下のアクションが予測されるとスコアが上昇:</div><div><br />いいね、リツイート、リプライ</div><div>動画視聴 (一定時間以上の動画)</div><div>フォロー</div><div>クリック、シェア、滞在時間</div><br /><div>In-Network（フォロー中） <br />フォローしているアカウントの投稿は優遇されます。</div><br /><div>新鮮な投稿 古すぎない<br />タイムリーな投稿が優先されます。</div><br /><div>動画コンテンツ 一定時間以上の動画は<br />特別な重み付けを受けます。</div><br /><br /><br /><div><span  style="font-size: 150%;">おすすめに除外されやすくなるポイント</span><br /><br /></div><div>ネガティブシグナル 以下が予測されると<br />スコアが低下:</div><br /><div>興味なし、ブロック、ミュート、報告</div><br /><div>ブロック・ミュートしたアカウント</div><div>完全に除外されます。</div><br /><div>ミュートキーワード</div><div>設定したキーワードを含む投稿は除外。</div><br /><div>自分自身の投稿</div><div>自分の投稿は「For You」から除外。</div><br /><div>既に見た投稿</div><div>過去に表示された投稿は除外（Bloom Filter使用）。</div><br /><div>古すぎる投稿</div><div>一定期間以上経過した投稿は除外。</div><br /><div>削除済み・スパム・暴力的コンテンツ</div><div>最終段階で除外されます。</div><br /><br /><br /><div><span  style="font-size: 150%;">スコアリングの仕組み</span><br /><br /></div><div>最終スコア = Σ (重み × 各アクションの予測確率)</div><br /><div>= P(いいね) × いいね重み</div><div>+ P(リツイート) × リツイート重み</div><div>+ P(リプライ) × リプライ重み</div><div>+ ...</div><div>+ P(ブロック) × ブロック重み (負の値)</div><div>+ P(ミュート) × ミュート重み (負の値)</div><div>処理順序:</div><br /><div>1. Phoenix Transformer → ML予測</div><div>2. Weighted Scorer → 重み付け結合</div><div>3. Author Diversity Scorer → 多様性調整</div><div>4. OON Scorer → In/Out-of-Network調整</div><div>5. Selection → 上位K件選択</div><br /><br /><br /><div><span  style="font-size: 150%;">ポジティブシグナルの重み</span><br /><br /></div><div>以下のアクションが予測されると、投稿のスコアが上昇します:</div><br /><div>アクション<span  style="white-space: pre;">	</span>説明<span  style="white-space: pre;">	</span>重要度</div><div>いいね (Favorite)<span  style="white-space: pre;">	</span>ユーザーがいいねする確率<span  style="white-space: pre;">	</span>⭐⭐⭐</div><div>リツイート (Retweet)<span  style="white-space: pre;">	</span>リツイートする確率<span  style="white-space: pre;">	</span>⭐⭐⭐</div><div>リプライ (Reply)<span  style="white-space: pre;">	</span>リプライする確率<span  style="white-space: pre;">	</span>⭐⭐⭐</div><div>引用ツイート (Quote)<span  style="white-space: pre;">	</span>引用ツイートする確率<span  style="white-space: pre;">	</span>⭐⭐</div><div>クリック (Click)<span  style="white-space: pre;">	</span>投稿をクリックする確率<span  style="white-space: pre;">	</span>⭐⭐</div><div>プロフィールクリック<span  style="white-space: pre;">	</span>投稿者のプロフィールをクリック<span  style="white-space: pre;">	</span>⭐⭐</div><div>動画視聴 (Video View)<span  style="white-space: pre;">	</span>動画を視聴する確率<span  style="white-space: pre;">	</span>⭐⭐⭐</div><div>画像展開 (Photo Expand)<span  style="white-space: pre;">	</span>画像を展開する確率<span  style="white-space: pre;">	</span>⭐⭐</div><div>シェア (Share)<span  style="white-space: pre;">	</span>外部にシェアする確率<span  style="white-space: pre;">	</span>⭐⭐</div><div>滞在時間 (Dwell)<span  style="white-space: pre;">	</span>投稿に滞在する時間<span  style="white-space: pre;">	</span>⭐⭐</div><div>フォロー (Follow Author)<span  style="white-space: pre;">	</span>投稿者をフォローする確率<span  style="white-space: pre;">	</span>⭐⭐⭐</div><br /><br /><div>実践的アドバイス<br /><br /></div><div>表示されやすくするには:</div><div>✅ エンゲージメントを促す投稿（いいね、RT、リプライされやすい）</div><div>✅ 動画・画像付きコンテンツ</div><div>✅ タイムリーな情報</div><div>✅ フォロワーとの関係構築</div><div><br />除外されないために:</div><div>❌ スパム的な投稿を避ける</div><div>❌ 暴力的・不適切なコンテンツを避ける</div><div>❌ ミュートキーワードに引っかからない</div><div>❌ 重複投稿を避ける</div><div><br /><br /><br /></div><div><span  style="font-size: 150%;">まとめ</span><br /><br /></div><div>今回のXのアルゴリズム更新のポイントは<br />「人間による調整を徹底的に排除し<br />AI（Grokベースのモデル）に判断を委ねたこと」にあります。</div><br /><div>システムは「フォロー内」と「フォロー外」の投稿を統合し<br />膨大なユーザー履歴から<br />「あなたが次にどのボタン（いいね、リプライ等）を押すか」<br />を精密に予測して並べ替えます。</div><br /><div>また、多様性を確保しつつ、不適切なコンテンツや重複を<br />二段階のフィルタリングで排除する<br />非常に高度かつクリーンな構成になっています。</div><br /><br />アルゴリズムの詳細コードを見たい方は<br />ぜひgithubの方を見てみてください<br /><br />それでは。<br /><br />
]]>
</content:encoded>
</item>

</rdf:RDF>
