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)