Math / app.py
OzoneAsai's picture
Update app.py
56d4d78
# 必要なライブラリをインポート
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}")