molQuiz / app.py
OzoneAsai's picture
Update app.py
e01ae8c verified
raw
history blame
13.7 kB
questions:dict[str,float]={
"MgCl2": 95.0,
"MgO": 40.0,
"MgF2": 62.0,
"MgS": 56.0,
"Mg(OH)2": 58.0,
"MgI2": 278.0,
"CaCl2": 111.0,
"CaO": 56.0,
"CaF2": 78.0,
"CaS": 72.0,
"Ca(OH)2": 74.0,
"CaI2": 294.0,
"ZnCl2": 136.0,
"ZnO": 81.0,
"ZnF2": 103.0,
"ZnS": 97.0,
"Zn(OH)2": 99.0,
"ZnI2": 319.0,
"NaCl": 58.5,
"Na2O": 62.0,
"NaF": 42.0,
"Na2S": 78.0,
"NaOH": 40.0,
"NaI": 150.0,
"KCl": 74.5,
"K2O": 94.0,
"KF": 58.0,
"K2S": 110.0,
"KOH": 56.0,
"KI": 166.0,
"HCl": 36.5,
"H2O": 18.0,
"HF": 20.0,
"H2S": 34.0,
"HOH": 18.0,
"HI": 128.0,
"CuCl": 99.0,
"Cu2O": 143.0,
"CuF": 82.5,
"Cu2S": 159.0,
"CuOH": 80.5,
"CuI": 190.5,
"CuCl2": 134.5,
"CuO": 79.5,
"CuF2": 101.5,
"CuS": 95.5,
"Cu(OH)2": 97.5,
"CuI2": 317.5,
"AgCl": 143.5,
"Ag2O": 232.0,
"AgF": 127.0,
"Ag2S": 248.0,
"AgOH": 125.0,
"AgI": 235.0,
"BaCl2": 208.0,
"BaO": 153.0,
"BaF2": 175.0,
"BaS": 169.0,
"Ba(OH)2": 171.0,
"BaI2": 391.0,
"FeCl2": 127.0,
"FeO": 72.0,
"FeF2": 94.0,
"FeS": 88.0,
"Fe(OH)2": 90.0,
"FeI2": 310.0,
"MnCl2": 126.0,
"MnO": 71.0,
"MnF2": 93.0,
"MnS": 87.0,
"Mn(OH)2": 89.0,
"MnI2": 309.0,
"PbCl2": 278.0,
"PbO": 223.0,
"PbF2": 245.0,
"PbS": 239.0,
"Pb(OH)2": 241.0,
"PbI2": 461.0,
"AlCl3": 133.5,
"Al2O3": 102.0,
"AlF3": 84.0,
"Al2S3": 150.0,
"Al(OH)3": 78.0,
"AlI3": 408.0,
"FeCl3": 162.5,
"Fe2O3": 160.0,
"FeF3": 113.0,
"Fe2S3": 208.0,
"Fe(OH)3": 107.0,
"FeI3": 437.0,
"NH4Cl": 53.5,
"(NH4)2O": 52.0,
"NH4F": 37.0,
"(NH4)2S": 68.0,
"NH4OH": 35.0,
"NH4I": 145.0,
"MgSO4": 120.0,
"MgCO3": 84.0,
"MgC2O4": 112.0,
"MgCrO4": 140.0,
"MgCr2O7": 240.0,
"MgS2O3": 136.0,
"Mg3(PO4)2": 262.0,
"CaSO4": 136.0,
"CaCO3": 100.0,
"CaC2O4": 128.0,
"CaCrO4": 156.0,
"CaCr2O7": 256.0,
"CaS2O3": 152.0,
"Ca3(PO4)2": 310.0,
"ZnSO4": 161.0,
"ZnCO3": 125.0,
"ZnC2O4": 153.0,
"ZnCrO4": 181.0,
"ZnCr2O": 185.0,
"ZnS2O3": 177.0,
"Zn3(PO4)2": 385.0,
"Na2SO4": 142.0,
"Na2CO3": 106.0,
"Na2C2O4": 134.0,
"Na2CrO4": 162.0,
"Na2Cr2O7": 262.0,
"Na2S2O3": 158.0,
"Na3PO4": 164.0,
"K2SO4": 174.0,
"K2CO3": 138.0,
"K2C2O4": 166.0,
"K2CrO4": 194.0,
"K2Cr2O7": 294.0,
"K2S2O3": 190.0,
"K3PO4": 212.0,
"H2SO4": 98.0,
"H2CO3": 62.0,
"H2C2O4": 90.0,
"H2CrO4": 118.0,
"H2Cr2O7": 218.0,
"H2S2O3": 114.0,
"H3PO4": 98.0,
"Cu2SO4": 223.0,
"Cu2CO3": 187.0,
"Cu2C2O4": 215.0,
"Cu2CrO4": 243.0,
"Cu2Cr2O7": 343.0,
"Cu2S2O3": 239.0,
"Cu3PO4": 285.5,
"CuSO4": 159.5,
"CuCO3": 123.5,
"CuC2O4": 151.5,
"CuCrO4": 179.5,
"CuCr2O7": 279.5,
"CuS2O3": 175.5,
"Cu3(PO4)2": 380.5,
"Ag2SO4": 312.0,
"Ag2CO3": 276.0,
"Ag2C2O4": 304.0,
"Ag2CrO4": 332.0,
"Ag2Cr2O7": 432.0,
"Ag2S2O3": 328.0,
"Ag3PO4": 419.0,
"BaSO4": 233.0,
"BaCO3": 197.0,
"BaC2O4": 225.0,
"BaCrO4": 253.0,
"BaCr2O7": 353.0,
"BaS2O3": 249.0,
"Ba3(PO4)2": 601.0,
"FeSO4": 152.0,
"FeCO3": 116.0,
"FeC2O4": 144.0,
"FeCrO4": 172.0,
"FeCr2O7": 272.0,
"FeS2O3": 168.0,
"Fe3(PO4)2": 358.0,
"MnSO4": 151.0,
"MnCO3": 115.0,
"MnC2O4": 143.0,
"MnCrO4": 171.0,
"MnCr2O)": 175.0,
"MnS2O3": 167.0,
"Mn3(PO4)2": 355.0,
"PbSO4": 303.0,
"PbCO3": 267.0,
"PbC2O4": 295.0,
"PbCrO4": 323.0,
"PbCr2O7": 423.0,
"PbS2O3": 319.0,
"Pb3(PO4)2": 811.0,
"Al2(SO4)3": 342.0,
"Al2(CO3)3": 234.0,
"Al2(C2O4)3": 318.0,
"Al2(CrO4)3": 402.0,
"Al2(Cr2O7)3": 702.0,
"Al2(S2O3)3": 390.0,
"AlPO4": 122.0,
"Fe2(SO4)3": 400.0,
"Fe2(CO3)3": 292.0,
"Fe2(C2O4)3": 376.0,
"Fe2(CrO4)3": 460.0,
"Fe2(Cr2O7)3": 760.0,
"Fe2(S2O3)3": 448.0,
"FePO4": 151.0,
"Mg(NO3)2": 148.0,
"(CH3COO)2Mg": 142.0,
"Mg(MnO4)2": 262.0,
"Ca(NO3)2": 164.0,
"(CH3COO)2Ca": 158.0,
"Ca(MnO4)2": 278.0,
"Zn(NO3)2": 189.0,
"(CH3COO)2Zn": 183.0,
"Zn(MnO4)2": 303.0,
"NaNO3": 85.0,
"CH3COONa": 82.0,
"Na(MnO4)": 142.0,
"KNO3": 101.0,
"CH3COOK": 98.0,
"K(MnO4)": 158.0,
"HNO3": 63.0,
"CH3COOH": 60.0,
"HMnO4": 120.0,
"CuNO3": 125.5,
"CH3COOCu": 122.5,
"CuMnO4": 182.5,
"Cu(NO3)2": 187.5,
"(CH3COO)2Cu": 181.5,
"Cu(MnO4)2": 301.5,
"AgNO3": 170.0,
"AgCH3COO": 167.0,
"AgMnO4": 227.0,
"Ba(NO3)2": 261.0,
"Ba(CH3COO)2": 255.0,
"Ba(MnO4)2": 375.0,
"Fe(NO3)2": 180.0,
"Fe(CH3COO)2": 174.0,
"Fe(MnO4)2": 294.0,
"Mn(NO3)2": 179.0,
"Mn(CH3COO)2": 173.0,
"MnNO3": 117.0,
"MnCH3COO": 114.0,
"Mn(MnO4)2": 293.0,
"Pb(NO3)2": 331.0,
"Pb(CH3COO)2": 325.0,
"Pb(MnO4)2": 445.0,
"Al(NO3)3": 213.0,
"Al(CH3COO)3": 204.0,
"Al(MnO4)3": 384.0,
"Fe(NO3)3": 242.0,
"Fe(CH3COO)3": 233.0,
"Fe(MnO4)3": 413.0,
"Mn(NO3)3": 241.0,
"Mn(CH3COO)3": 232.0,
"Mn(MnO4)3": 412.0,
"Pb(NO3)3": 393.0,
"Pb(CH3COO)3": 384.0,
"Pb(MnO4)3": 564.0,
"Al(NO3)2": 151.0,
"Al(CH3COO)2": 145.0,
"Al(MnO4)2": 265.0,
}
from flask import Flask, render_template, request, redirect, url_for, session
import random
import sympy as sp
app = Flask(__name__)
app.secret_key = 'your_secret_key' # セッションのための秘密鍵
# シンボルの定義と説明
symbols_info = {
'solute_mass': '溶質の質量 (g)',
'solution_mass': '溶液の質量 (g)',
'moles_of_solute': '溶質のモル数 (mol)',
'volume_of_solution': '溶液の体積 (L)',
'mass': '質量 (g)',
'volume': '体積 (mL)',
'density': '密度 (g/mL)',
'molarity': 'モル濃度 (mol/L)',
'mass_percent': '質量パーセント濃度 (%)'
}
solute_mass, solution_mass, moles_of_solute, volume_of_solution, mass, volume, density, molarity, mass_percent = sp.symbols(
'solute_mass solution_mass moles_of_solute volume_of_solution mass volume density molarity mass_percent')
# 質量パーセント濃度を計算する関数
def calculate_mass_percent(solute_mass, solution_mass):
mass_percent = (solute_mass / solution_mass) * 100
return round(float(mass_percent), 3)
def find_mass_percent_value(solute_mass_value, solution_mass_value):
equation = sp.Eq(mass_percent, (solute_mass / solution_mass) * 100)
result = sp.solve(equation.subs({solute_mass: solute_mass_value, solution_mass: solution_mass_value}), mass_percent)
return round(float(result[0]), 3)
# モル濃度を計算する関数
def calculate_molarity(moles_of_solute, volume_of_solution):
molarity = moles_of_solute / volume_of_solution
return round(float(molarity), 3)
def find_molarity_value(moles_of_solute_value, volume_of_solution_value):
equation = sp.Eq(molarity, moles_of_solute / volume_of_solution)
result = sp.solve(equation.subs({moles_of_solute: moles_of_solute_value, volume_of_solution: volume_of_solution_value}), molarity)
return round(float(result[0]), 3)
# 密度を計算する関数
def calculate_density(mass, volume):
density = mass / volume
return round(float(density), 3)
def find_density_value(mass_value, volume_value):
equation = sp.Eq(density, mass / volume)
result = sp.solve(equation.subs({mass: mass_value, volume: volume_value}), density)
return round(float(result[0]), 3)
# 循環小数をチェックする関数
def is_recurring(decimal_str):
if '.' in decimal_str:
fractional_part = decimal_str.split('.')[1]
for i in range(1, len(fractional_part)):
if fractional_part[:i] == fractional_part[i:2*i]:
return True
return False
# 問題文テンプレート生成関数
def generate_problem_statement(method_name, param_values):
templates = {
'calculate_mass_percent': [
"溶質の質量が {solute_mass} g で、溶液の質量が {solution_mass} g の場合、質量パーセント濃度を求めなさい。",
"質量パーセント濃度が {mass_percent}% で、溶液の質量が {solution_mass} g の場合、溶質の質量を求めなさい。",
"質量パーセント濃度が {mass_percent}% で、溶質の質量が {solute_mass} g の場合、溶液の質量を求めなさい。"
],
'calculate_molarity': [
"溶質のモル数が {moles_of_solute} mol で、溶液の体積が {volume_of_solution} L の場合、モル濃度を求めなさい。",
"モル濃度が {molarity} mol/L で、溶液の体積が {volume_of_solution} L の場合、溶質のモル数を求めなさい。",
"モル濃度が {molarity} mol/L で、溶質のモル数が {moles_of_solute} mol の場合、溶液の体積を求めなさい。"
],
'calculate_density': [
"質量が {mass} g で、体積が {volume} mL の場合、密度を求めなさい。",
"密度が {density} g/mL で、体積が {volume} mL の場合、質量を求めなさい。",
"密度が {density} g/mL で、質量が {mass} g の場合、体積を求めなさい。"
]
}
template_list = templates.get(method_name, ["問題文の生成に失敗しました。"])
template = random.choice(template_list)
return template.format(**param_values)
# 公式生成関数
def generate_equation_string(method_name, param_values):
try:
equations = {
'calculate_mass_percent': "質量パーセント濃度 = (溶質の質量 / 溶液の質量) * 100\n質量パーセント濃度 = ({solute_mass} / {solution_mass}) * 100".format(**param_values),
'calculate_molarity': "モル濃度 = 溶質のモル数 / 溶液の体積\nモル濃度 = {moles_of_solute} / {volume_of_solution}".format(**param_values),
'calculate_density': "密度 = 質量 / 体積\n密度 = {mass} / {volume}".format(**param_values),
}
return equations.get(method_name, "公式の生成に失敗しました。")
except KeyError as e:
return f"公式の生成中にエラーが発生しました: {e}"
# 乱数を用いて計算方法を決定し問題を作成する関数
def generate_problem():
methods = [
('calculate_mass_percent', ['solute_mass', 'solution_mass', 'mass_percent']),
('calculate_molarity', ['moles_of_solute', 'volume_of_solution', 'molarity']),
('calculate_density', ['mass', 'volume', 'density']),
]
while True:
method_name, params = random.choice(methods)
param_values = {param: random.randint(1, 100) for param in params}
missing_param = random.choice(params)
param_values[missing_param] = 'x'
equation = generate_equation_string(method_name, param_values).split('\n')[1]
solution = solve_equation(equation, 'x')
if solution and all(isinstance(s, (int, float)) for s in solution):
solution_value = round(float(solution[0]), 16)
solution_str = f'{solution_value:.16f}'
if is_recurring(solution_str):
continue
if len(str(solution_value).split('.')[1]) <= 4:
break
param_values[missing_param] = solution_value
problem_statement = generate_problem_statement(method_name, param_values)
equation_string = generate_equation_string(method_name, param_values)
return method_name, param_values, solution_value, problem_statement, equation_string
@app.route('/', methods=['GET', 'POST'])
def index():
if request.method == 'POST':
try:
user_input = float(request.form['user_input'])
solution = float(request.form['solution'])
correct = abs(user_input - solution) < 1e-3
except ValueError:
correct = False
user_input = None
solution = None
return render_template('result.html', correct=correct, user_input=user_input, solution=solution, problem_statement=session.get('problem_statement'), equation_string=session.get('equation_string'))
else:
method_name, param_values, solution, problem_statement, equation_string = generate_problem()
session['problem_statement'] = problem_statement
session['solution'] = solution
session['method_name'] = method_name
session['param_values'] = param_values
session['equation_string'] = equation_string
return render_template('index.html', method_name=method_name, param_values=param_values, solution=solution, problem_statement=problem_statement, symbols_info=symbols_info)
@app.route('/retry', methods=['GET', 'POST'])
def retry():
if request.method == 'POST':
return redirect(url_for('index'))
if 'method_name' not in session or 'param_values' not in session or 'solution' not in session or 'problem_statement' not in session or 'equation_string' not in session:
return redirect(url_for('index'))
return render_template('index.html', method_name=session.get('method_name'), param_values=session.get('param_values'), solution=session.get('solution'), problem_statement=session.get('problem_statement'), symbols_info=symbols_info, equation_string=session.get('equation_string'))
@app.route('/new')
def new_problem():
return redirect(url_for('index'))
if __name__ == '__main__':
app.run(debug=True, host="0.0.0.0", port=7860)