matrix_dot / app.py
Yinxing's picture
Update app.py
7391a59 verified
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()