サイトアイコン アマチュア無線局JS2IIU

【Streamlit】コードデバッグゲームアプリの作成

こんにちは、JS2IIUです。
Streamlitを使ったアプリを作ってみたいと思って思いついたアイデアが生成AIでプログラムに関する簡単なゲームを作ることでした。実際に作ってみたので中身を紹介していきます。今回もよろしくお願いします。

はじめに

本記事では、Streamlitを活用してプログラミングのデバッグを競うアプリを作成する方法を紹介します。このアプリでは、OpenAIのAPIを使用してバグのあるPythonコードを生成し、ユーザーが正しく修正できるかを競う仕組みになっています。

アプリの概要

このアプリでは以下の機能を実装します。

必要なライブラリ

このアプリを実行するには以下のライブラリが必要です。

Python
pip install streamlit openai pandas

コードの解説

https://js2iiu.com/wp-content/uploads/2025/03/code-debug.mov

最初にコードの全体像を示します。

Python
import streamlit as st
import time
import random
import pandas as pd
import openai
import json

# OpenAI APIキーの設定(環境変数を利用した方が良い)
openai.api_key = "YOUR_API_KEY_HERE"

def generate_buggy_code():
    """OpenAIのgpt-4oを使用してバグのあるコードを生成する"""
    prompt = """
    Generate a simple Python code snippet with a common bug. 
    Provide a short description of the bug and the buggy code in valid JSON format:
    {
        "question": "Short description of the bug",
        "buggy": "Python code with a bug",
        "solution": "Corrected version of the code"
    }
    Ensure the JSON output is valid and does not contain any additional text or formatting.
    """

    response = openai.chat.completions.create(
        model="gpt-4o", 
        messages=[{"role": "system", "content": "You are a helpful assistant."},
                  {"role": "user", "content": prompt}]
    )

    # OpenAIのレスポンス取得
    content = response.choices[0].message.content

    # もしコードブロックがあれば削除
    if content.startswith("```json"):
        content = content[7:]  # 最初の ```json を削除
    if content.endswith("```"):
        content = content[:-3]  # 最後の ``` を削除

    return json.loads(content)  # JSONパース

# セッション状態を初期化
if "start_time" not in st.session_state:
    st.session_state.start_time = None
if "end_time" not in st.session_state:
    st.session_state.end_time = None
if "selected_problem" not in st.session_state:
    st.session_state.selected_problem = generate_buggy_code()
if "ranking" not in st.session_state:
    st.session_state.ranking = []

st.title("プログラミングコードデバッグレース")
st.write(st.session_state.selected_problem["question"])

st.code(st.session_state.selected_problem["buggy"], language="python")

user_code = st.text_area("修正後のコードを入力してください:")

if st.button("提出"):
    if st.session_state.start_time is None:
        st.session_state.start_time = time.time()

    try:
        exec_locals = {}
        exec(user_code, {}, exec_locals)  # ユーザーのコードを実行
        expected_locals = {}
        exec(st.session_state.selected_problem["solution"], {}, expected_locals)

        if exec_locals == expected_locals:
            st.session_state.end_time = time.time()
            elapsed_time = st.session_state.end_time - st.session_state.start_time
            st.success(f"正解!修正時間: {elapsed_time:.2f} 秒")

            # ランキングに追加
            st.session_state.ranking.append(elapsed_time)
            st.session_state.ranking.sort()

            # 新しい問題を取得
            st.session_state.selected_problem = generate_buggy_code()
            st.session_state.start_time = None
            st.session_state.end_time = None
        else:
            st.error("出力が正しくありません。修正を続けてください!")
    except Exception as e:
        st.error(f"エラーが発生しました: {e}")

if st.session_state.ranking:
    st.subheader("ランキング")
    df = pd.DataFrame({"順位": range(1, len(st.session_state.ranking) + 1), "修正時間 (秒)": st.session_state.ranking})
    st.dataframe(df)

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

Python
import streamlit as st
import time
import random
import pandas as pd
import openai
import json

このコードでは、Streamlitを使用してアプリのフロントエンドを作成し、openai を利用してバグのあるコードを生成します。

2. OpenAI APIの設定

Python
openai.api_key = "YOUR_API_KEY_HERE"

APIキーを環境変数に設定し、OpenAIのサービスを利用できるようにします。

3. バグのあるコードを生成

Python
def generate_buggy_code():
    """OpenAIのGPT-4oを使用してバグのあるコードを生成する"""
    prompt = """
    Generate a simple Python code snippet with a common bug.
    Provide a short description of the bug and the buggy code in valid JSON format:
    {
        "question": "Short description of the bug",
        "buggy": "Python code with a bug",
        "solution": "Corrected version of the code"
    }
    Ensure the JSON output is valid and does not contain any additional text or formatting.
    """

    response = openai.chat.completions.create(
        model="gpt-4o",
        messages=[{"role": "system", "content": "You are a helpful assistant."},
                  {"role": "user", "content": prompt}]
    )

    content = response.choices[0].message.content

    if content.startswith("```json"):
        content = content[7:]
    if content.endswith("```"):
        content = content[:-3]

    return json.loads(content)

GPT-4oを利用して、バグのあるコードを生成し、JSONフォーマットで取得します。

4. セッション状態の初期化

Python
if "start_time" not in st.session_state:
    st.session_state.start_time = None
if "end_time" not in st.session_state:
    st.session_state.end_time = None
if "selected_problem" not in st.session_state:
    st.session_state.selected_problem = generate_buggy_code()
if "ranking" not in st.session_state:
    st.session_state.ranking = []

セッションを利用して、デバッグレースの状態を管理します。

5. アプリのUI作成

Python
st.title("プログラミングコードデバッグレース")
st.write(st.session_state.selected_problem["question"])

st.code(st.session_state.selected_problem["buggy"], language="python")

user_code = st.text_area("修正後のコードを入力してください:")

StreamlitのUIを使用して、問題文とバグのあるコードを表示し、ユーザーが修正後のコードを入力できるようにします。

6. 提出ボタンと判定処理

Python
if st.button("提出"):
    if st.session_state.start_time is None:
        st.session_state.start_time = time.time()

    try:
        exec_locals = {}
        exec(user_code, {}, exec_locals)
        expected_locals = {}
        exec(st.session_state.selected_problem["solution"], {}, expected_locals)

        if exec_locals == expected_locals:
            st.session_state.end_time = time.time()
            elapsed_time = st.session_state.end_time - st.session_state.start_time
            st.success(f"正解!修正時間: {elapsed_time:.2f} 秒")

            st.session_state.ranking.append(elapsed_time)
            st.session_state.ranking.sort()

            st.session_state.selected_problem = generate_buggy_code()
            st.session_state.start_time = None
            st.session_state.end_time = None
        else:
            st.error("出力が正しくありません。修正を続けてください!")
    except Exception as e:
        st.error(f"エラーが発生しました: {e}")

ユーザーの入力したコードを実行し、正しく修正されているか判定します。

7. ランキングの表示

Python
if st.session_state.ranking:
    st.subheader("ランキング")
    df = pd.DataFrame({"順位": range(1, len(st.session_state.ranking) + 1), "修正時間 (秒)": st.session_state.ranking})
    st.dataframe(df)

修正時間のランキングを表示します。

まとめ

このアプリは、プログラミングのデバッグスキルを競うゲーム形式のアプリです。Streamlitの簡単な記述でUIを構築し、OpenAIのGPT-4oを活用することで、様々なバグのあるコードを動的に生成できます。

このアプリを応用すれば、競技プログラミングや学習用の問題作成などにも利用可能です。ぜひ、自分なりにカスタマイズして活用してください!

最後に、書籍のPRです。

最新のOpenAIのチャットAPIの使い方もしっかりと解説されている良書です。2024年11月初版発行、「LangChainとLangGraphによるRAG・AIエージェント[実践]入門」西見、吉田、大嶋著。

最後まで読んでいただきありがとうございます。

モバイルバージョンを終了