# 必要なライブラリをインポート import streamlit as st from sympy import symbols, expand, factor, Eq, solve, diff, N, simplify, factorial, parse_expr, sqrt import math from scipy.optimize import fsolve import numpy as np import random # Streamlitアプリのタイトルを設定 st.title("数学関数アプリ") selected_function = st.sidebar.selectbox("機能を選択", ["因数分解", "展開", "方程式", "連立方程式", "nPm", "nCm", "多項式への代入計算", "関数の交点", "三平方の定理", "素因数分解", "普通の記述式計算","問題生成"]) x=symbols("x") # サイドバーに説明を追加 st.sidebar.header("構文説明") st.sidebar.markdown("$2x$と書きたい場合は「$2*x$」と、記述するように。また、平方根は$sqrt(2)$というように記述するように。") st.sidebar.markdown("また、平方根は$sqrt(2)$というように記述するように。") st.sidebar.markdown("割り算は`/`を使うように。掛け算は`*`を使うように。") st.sidebar.markdown("--------------") st.sidebar.header("機能説明") st.sidebar.markdown("## 因数分解(2x=2*x)") st.sidebar.markdown("## (2x=2*x)") #st.sidebar.markdown("$2x$と書きたい場合は「$2*x$」と、きじゅつするように。") st.sidebar.markdown("## 方程式(2x=2*x)") st.sidebar.markdown("## 連立方程式(2x=2*x)") st.sidebar.markdown("## nPm, nCm") st.sidebar.markdown("## 多項式への代入計算") st.sidebar.markdown("## ふたつの関数の交点の計算") st.sidebar.markdown("## 三平方の定理(空欄補充)") st.sidebar.markdown("## 素因数分解(Sympy)") st.sidebar.markdown("## 記述式計算") # Symbolの定義 #user_defined_symbol= symbols("x") #user_defined_symbol = st.sidebar.text_input("Symbolを定義してください(カンマ区切り):") # カンマ区切りで複数のSymbolを作成 #user_defined_symbols = symbols(user_defined_symbol.replace(" ", "").split(",")) # メインのコンテンツを作成 # 因数分解 if selected_function == "因数分解": expression = st.text_input("因数分解する式を入力してください:") if expression: x = symbols('x') factored_expression = factor(expression) # シンボルの代入 #for symbol in user_defined_symbols: # factored_expression = factor(expression) st.success(f"因数分解結果: {factored_expression}") st.latex(factored_expression) # 展開(Sympy) elif selected_function == "展開": expression = st.text_input("展開する式を入力してください:") if expression: result = expand(expression) st.success(f"展開結果: {result}") st.latex(result) # 方程式(Sympy) # 方程式(Sympy) # 方程式(Sympy) elif selected_function == "方程式": equation = st.text_input("解きたい方程式を入力してください:") if equation: x = symbols('x', real=True) solution = solve(Eq(eval(equation),0), x) st.success(f"方程式の解: {solution}") st.latex(solution) # 連立方程式(Sympy) elif selected_function == "連立方程式": eq1 = st.text_input("1つ目の方程式を入力してください:") eq2 = st.text_input("2つ目の方程式を入力してください:") if eq1 and eq2: x, y = symbols('x y', real=True) solution = solve([Eq(eval(eq1), 0), Eq(eval(eq2), 0)], (x, y)) st.success(f"連立方程式の解: {solution}") st.latex(solution) # nPm elif selected_function == "nPm": n = st.number_input("nを入力してください:", min_value=0, step=1) m = st.number_input("mを入力してください:", min_value=0, step=1) if n >= m: result = factorial(n) / factorial(n - m) st.success(f"{n}P{m}の結果: {result}") # nCm elif selected_function == "nCm": n = st.number_input("nを入力してください:", min_value=0, step=1) m = st.number_input("mを入力してください:", min_value=0, step=1) if n >= m: result = math.comb(n, m) st.success(f"{n}C{m}の結果: {result}") st.latex(result) # 多項式への代入計算 elif selected_function == "多項式への代入計算": poly_expression = st.text_input("多項式を入力してください:") value_to_substitute = st.number_input("代入する値を入力してください:") if poly_expression: x = symbols('x', real=True) poly = simplify(poly_expression) result = poly.subs(x, value_to_substitute) st.success(f"代入計算の結果: {result}") st.latex(result) # ふたつの関数の交点の計算 elif selected_function == "関数の交点": func1_expression = st.text_input("1つ目の関数を入力してください:") func2_expression = st.text_input("2つ目の関数を入力してください:") if func1_expression and func2_expression: x = symbols('x', real=True) func1 = simplify(parse_expr(func1_expression)) func2 = simplify(parse_expr(func2_expression)) # 関数を数値的に解くためのラムダ関数 equation_system = lambda x: [func1.subs('x', x[0]) - func2.subs('x', x[0]), func1.subs('x', x[1]) - func2.subs('x', x[1])] # 初期値の設定 initial_guess = [0, 0] # fsolveを使用して交点を求める intersection_points = fsolve(equation_system, initial_guess) st.success(f"関数の交点の座標: {tuple(intersection_points)}") st.latex(tuple(intersection_points)) # 三平方の定理(空欄補充) elif selected_function == "三平方の定理": case = st.radio("三平方の定理のケースを選択してください:", ["Case1", "Case2", "Case3"]) if case == "Case1": a = st.number_input("aの値を入力してください:") b = st.number_input("bの値を入力してください:") c_squared = a**2 + b**2 st.success(f"三平方の定理の結果: a^2 + b^2 = c^2, c^2 = {c_squared}") elif case == "Case2": a = st.number_input("aの値を入力してください:") c = st.number_input("cの値を入力してください:") b_squared = c**2 - a**2 if b_squared >= 0: b = b_squared**0.5 st.success(f"三平方の定理の結果: a^2 + b^2 = c^2, b^2 = {b_squared}, b = {b}") else: st.error("無効な値です。b^2は負になりません。") elif case == "Case3": b = st.number_input("bの値を入力してください:") c = st.number_input("cの値を入力してください:") a_squared = c**2 - b**2 if a_squared >= 0: a = a_squared**0.5 st.success(f"三平方の定理の結果: a^2 + b^2 = c^2, a^2 = {a_squared}, a = {a}") else: st.error("無効な値です。a^2は負になりません。") # 素因数分解(Sympy) elif selected_function == "素因数分解": expression = st.text_input("素因数分解する式を入力してください:") if expression: factored_expression = factor(expression) st.success(f"素因数分解結果: {factored_expression}") st.latex(factored_expression) elif selected_function == "普通の記述式計算": expression = st.text_input("計算したい数式を入力してください:") if expression: try: result = parse_expr(expression) st.success(f"計算結果: {result}") st.latex(result) except Exception as e: st.error(f"エラー: {e}") # 問題生成 # 問題生成 # 問題生成 elif selected_function == "問題生成": problem_option = st.radio("問題オプションを選択してください:", ["四則演算", "因数分解", "方程式","ヘロンの公式"]) if not problem_option: st.warning("少なくとも1つの問題オプションを選択してください。") else: # 乱数の生成範囲指定 min_value = st.number_input("乱数の最小値を入力してください:", value=-10) max_value = st.number_input("乱数の最大値を入力してください:", value=10) # 生成ボタン generate_button = st.button("問題を生成する") if generate_button: generated_problems = [] # 四則演算の問題生成 if problem_option == "四則演算": # 例: 3 + 5 * 2 num1 = random.randint(min_value, max_value) num2 = random.randint(min_value, max_value) operator = random.choice(["+", "-", "*", "/"]) problem = f"{num1} {operator} {num2}" generated_problems.append(problem) # 因数分解の問題生成 elif problem_option == "因数分解": # 例: x**2 + 5*x + 6 a = random.randint(min_value, max_value) b = random.randint(min_value, max_value) init_problem = f"(x + {a})*(x + {b})" expression = init_problem if expression: result = expand(expression) st.success(f"問題: {result}") st.latex(result) generated_problems.append(result) # 方程式の問題生成 elif problem_option == "ヘロンの公式": from sympy import sqrt # 一辺の長さが2の倍数になる正三角形 st.caption("負の数を乱数に入れても意味はないですよ...") side_length = random.randint(abs(min_value), abs(max_value)) * 2 # ヘロンの公式: s = (a + b + c) / 2 s = side_length * 3 / 2 # 三角形の面積 area = math.sqrt(s * (s - side_length) ** 3) problem = f"一辺の長さが{side_length}の正三角形の面積" generated_problems.append(problem) st.success(f"問題: {problem}") acr = "{" acrE="}" ReProblem =f"sqrt({s} * ({s} - {side_length}) * ({s} - {side_length}) * ({s} - {side_length}))" ReProblem=str(ReProblem) #ReProblem =equation# =# "sqrt({s}*({s}-{side_length})*({s}-{side_length})*({s}-{side_length}))" #equation = equation.replace("{sidelength}", str(side_length)) # #equation = equation.replace("{s}", str(s)) #ReProblem = equation st.latex(ReProblem) st.latex("sqrt(30.0∗(30.0−20)∗(30.0−20)∗(30.0−20))") st.markdown(f"${ReProblem}$") st.success("生成された問題:") for idx, problem in enumerate(generated_problems, start=1): st.write(f"{idx}. {problem}")