import gradio as gr import numpy as np try: # demo close demo.close() except: pass import gradio as gr import numpy as np # --- LaTeX形式で行列を表現 --- def matrix_to_latex(M, name="A"): rows = [" & ".join(map(lambda x: f"{x:.1f}", row)) for row in M] body = " \\\\ ".join(rows) return f"{name} = \\begin{{bmatrix}} {body} \\end{{bmatrix}}" # --- ランダム行列生成 --- def random_matrix(rows, cols, min_val, max_val, step): values = np.arange(min_val, max_val + step / 2, step) return np.random.choice(values, size=(rows, cols)) # --- 問題生成 --- def generate_problem(rows_A, cols_A, cols_B, min_val, max_val, step): rows_B = cols_A # 行列積が可能なように調整 A = random_matrix(int(rows_A), int(cols_A), min_val, max_val, step) B = random_matrix(int(rows_B), int(cols_B), min_val, max_val, step) md = ( "### 以下の行列の積を求めよ:\n\n" + "$$ " + matrix_to_latex(A, "A") + " $$\n\n" + "$$ " + matrix_to_latex(B, "B") + " $$\n\n" + "求めるもの:$$ A \\times B $$" ) # 新しい問題と一緒に解答欄を空にリセット return (A.tolist(), B.tolist(), md, "") # --- 解答生成 --- def show_answer(A, B): A = np.array(A); B = np.array(B) C = A @ B steps = [] for i in range(C.shape[0]): for j in range(C.shape[1]): terms = [f"{A[i,k]:.1f}\\times{B[k,j]:.1f}" for k in range(A.shape[1])] steps.append(f"$c_{{{i+1}{j+1}}} = " + " + ".join(terms) + f" = {C[i,j]:.1f}$") md = ( "### 【解答】\n\n" + "$$ " + matrix_to_latex(C, "C") + " $$\n\n" + "### 【計算手順】\n\n" + "\n\n".join(steps) ) return md # --- Gradio UI設定 --- latex_delims = [ {"left": "$$", "right": "$$", "display": True}, {"left": "$", "right": "$", "display": False}, ] with gr.Blocks(title="行列積ランダム出題") as demo: gr.Markdown("## 🎲 ランダム行列積クイズ\n" "行列サイズや数値範囲を調整して、練習用の問題を自動生成できます。") with gr.Accordion("⚙️ パラメータ設定", open=False): with gr.Row(): rows_A = gr.Slider(2, 4, value=3, step=1, label="Aの行数") cols_A = gr.Slider(2, 4, value=3, step=1, label="Aの列数(=Bの行数)") cols_B = gr.Slider(2, 4, value=3, step=1, label="Bの列数") with gr.Row(): min_val = gr.Number(value=-5.0, label="最小値(例:-5)") max_val = gr.Number(value=5.0, label="最大値(例:5)") step_val = gr.Number(value=0.5, label="刻み幅(例:0.5)") A_state = gr.State() B_state = gr.State() problem_md = gr.Markdown("", latex_delimiters=latex_delims, label="問題") answer_md = gr.Markdown("", latex_delimiters=latex_delims, label="解答") with gr.Row(): gen_btn = gr.Button("🔄 問題を再作成", variant="primary") ans_btn = gr.Button("💡 解答提示", variant="secondary") # 新しい問題作成時に、解答欄もクリア gen_btn.click( fn=generate_problem, inputs=[rows_A, cols_A, cols_B, min_val, max_val, step_val], outputs=[A_state, B_state, problem_md, answer_md] ) ans_btn.click( fn=show_answer, inputs=[A_state, B_state], outputs=answer_md ) demo.launch()