| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952 |
- # -*- coding: utf-8 -*-
- """初始化初中化学题库与知识图谱数据"""
- import sys
- import os
- sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
- from app import (
- app,
- db,
- Question,
- KnowledgePoint,
- KnowledgeRelation,
- CurriculumTopic,
- ChemistryQuestionBank,
- )
- def seed_questions():
- """初中化学题库示例"""
- if Question.query.first():
- print("题库已有数据,跳过")
- return
- data = [
- ("下列物质中,不属于电解质的是?", "NaCl", "CH₃COOH", "Cu (金属铜)", "NaOH", "C", "电解质"),
- ("下列关于化学反应速率的说法正确的是?", "反应速率是指反应物浓度的减少", "反应速率是指生成物浓度的增加",
- "反应速率可以用单位时间内反应物浓度的减少来表示", "反应速率与反应物的性质无关", "C", "化学反应速率"),
- ("下列属于氧化还原反应的是?", "CaCO₃ 高温分解", "NaOH + HCl = NaCl + H₂O",
- "2H₂ + O₂ 点燃 2H₂O", "AgNO₃ + NaCl = AgCl↓ + NaNO₃", "C", "氧化还原反应"),
- ("物质的量的单位是?", "g", "mol", "L", "m³", "B", "物质的量"),
- ("元素周期表中,同周期元素从左到右,原子半径变化规律是?", "逐渐增大", "逐渐减小",
- "先增大后减小", "不变", "B", "元素周期律"),
- ("下列物质能在氧气中燃烧并产生大量白烟的是?", "碳", "硫", "磷", "铁丝", "C", "氧气性质"),
- ("原子核由什么组成?", "质子和电子", "质子和中子", "中子和电子", "质子、中子和电子", "B", "原子结构"),
- ("酸溶液能使紫色石蕊试液变?", "红色", "蓝色", "无色", "紫色", "A", "酸碱指示剂"),
- ("催化剂在化学反应中的作用是?", "增加反应物", "减少生成物", "改变化学反应速率", "改变反应条件", "C", "催化剂"),
- ("离子反应发生的条件是?", "有沉淀、气体或水生成", "有催化剂", "加热", "加压", "A", "离子反应"),
- ]
- for content, a, b, c, d, correct, kp in data:
- db.session.add(Question(
- content=content, option_a=a, option_b=b, option_c=c, option_d=d,
- correct_option=correct, knowledge_point=kp or None
- ))
- db.session.commit()
- print("已插入 %d 道题目" % len(data))
- def seed_curriculum_topics():
- """初始化课程主题"""
- if CurriculumTopic.query.first():
- print("curriculum_topics 已有数据,跳过")
- return
- topics = [
- dict(name="物质分类", phase="初中", chapter="第一章 走进化学世界",
- description="区分纯净物、混合物、单质、化合物等"),
- dict(name="原子结构", phase="初中", chapter="第二章 走进原子世界",
- description="认识质子、中子、电子及核外电子排布"),
- dict(name="化学方程式", phase="初中", chapter="基本概念与化学方程式",
- description="化学反应的符号表示及配平"),
- dict(name="化学实验基础", phase="初中", chapter="化学实验基本方法",
- description="常用仪器、操作规范、安全意识"),
- dict(name="溶液与浓度", phase="初中", chapter="溶液",
- description="溶液配制、溶质质量分数等"),
- dict(name="金属及其化合物", phase="初中", chapter="金属活动性顺序",
- description="金属与酸、盐溶液的反应与置换"),
- dict(name="酸碱盐", phase="初中", chapter="酸碱盐",
- description="常见酸碱盐的性质及反应"),
- dict(name="气体制取与性质", phase="初中", chapter="常见气体",
- description="氧气、二氧化碳等的制取与性质"),
- dict(name="微观粒子模型", phase="初中", chapter="微观与宏观",
- description="分子、原子、离子等微观示意图"),
- dict(name="化学安全与环保", phase="初中", chapter="化学与生活",
- description="安全操作、事故应急与环保意识"),
- ]
- db.session.bulk_save_objects([CurriculumTopic(**t) for t in topics])
- db.session.commit()
- print("已插入 %d 个课程主题" % len(topics))
- def seed_chemistry_question_bank():
- """多题型统一题库(每类大约 10~20 题,后续可自行扩展)"""
- if ChemistryQuestionBank.query.first():
- print("chemistry_question_bank 已有数据,跳过")
- return
- questions = []
- # 1. 基础概念辨析题(choice)约 50 题
- choice_data = [
- dict(
- difficulty="easy",
- topic="物质分类",
- content="下列物质属于纯净物的是:A.空气 B.矿泉水 C.蒸馏水 D.泥水",
- answer_schema={
- "options": {"A": "空气", "B": "矿泉水", "C": "蒸馏水", "D": "泥水"},
- "correct": ["C"],
- },
- hint="纯净物只有一种微粒组成",
- ),
- dict(
- difficulty="medium",
- topic="原子结构",
- content="原子核中一定含有的粒子是:A.质子 B.中子 C.电子 D.离子",
- answer_schema={
- "options": {"A": "质子", "B": "中子", "C": "电子", "D": "离子"},
- "correct": ["A"],
- },
- hint="注意氢原子的特殊性",
- ),
- dict(
- difficulty="easy",
- topic="化学方程式",
- content="催化剂在化学反应中的作用是:A.提高产物质量 B.改变反应速率 C.增加反应物浓度 D.减少能量消耗",
- answer_schema={
- "options": {
- "A": "提高产物质量",
- "B": "改变反应速率",
- "C": "增加反应物浓度",
- "D": "减少能量消耗",
- },
- "correct": ["B"],
- },
- hint="只改变速率,不改反应前后物质总能量",
- ),
- dict(
- difficulty="easy",
- topic="物质分类",
- content="下列属于金属单质的是:A.Fe B.Fe₂O₃ C.NaCl D.H₂O",
- answer_schema={
- "options": {"A": "Fe", "B": "Fe₂O₃", "C": "NaCl", "D": "H₂O"},
- "correct": ["A"],
- },
- hint="元素与化合物的区分",
- ),
- dict(
- difficulty="easy",
- topic="物质分类",
- content="下列属于混合物的是:A.液氯 B.蒸馏水 C.干冰 D.生理盐水",
- answer_schema={
- "options": {
- "A": "液氯",
- "B": "蒸馏水",
- "C": "干冰",
- "D": "生理盐水",
- },
- "correct": ["D"],
- },
- hint="盐溶解在水中形成混合物",
- ),
- dict(
- difficulty="medium",
- topic="酸碱盐",
- content="能使紫色石蕊溶液变红的是:A.NaCl溶液 B.NaOH溶液 C.HCl溶液 D.蒸馏水",
- answer_schema={
- "options": {
- "A": "NaCl溶液",
- "B": "NaOH溶液",
- "C": "HCl溶液",
- "D": "蒸馏水",
- },
- "correct": ["C"],
- },
- hint="酸使石蕊变红,碱使石蕊变蓝",
- ),
- dict(
- difficulty="easy",
- topic="酸碱盐",
- content="下列属于碱的是:A.NaCl B.NaOH C.H₂SO₄ D.CO₂",
- answer_schema={
- "options": {"A": "NaCl", "B": "NaOH", "C": "H₂SO₄", "D": "CO₂"},
- "correct": ["B"],
- },
- hint="含有金属阳离子和 OH⁻ 的化合物",
- ),
- dict(
- difficulty="medium",
- topic="金属及其化合物",
- content="在金属活动性顺序中,能从 CuSO₄ 溶液中置换出铜的金属是:A.Cu B.Ag C.Fe D.Hg",
- answer_schema={
- "options": {"A": "Cu", "B": "Ag", "C": "Fe", "D": "Hg"},
- "correct": ["C"],
- },
- hint="Fe 比 Cu 活泼,可置换",
- ),
- dict(
- difficulty="easy",
- topic="化学安全与环保",
- content="下列行为有利于环境保护的是:A.露天焚烧垃圾 B.乱倒废酸 C.使用无磷洗衣粉 D.随意排放含重金属废水",
- answer_schema={
- "options": {
- "A": "露天焚烧垃圾",
- "B": "乱倒废酸",
- "C": "使用无磷洗衣粉",
- "D": "随意排放含重金属废水",
- },
- "correct": ["C"],
- },
- hint="无磷洗衣粉可减轻水体富营养化",
- ),
- dict(
- difficulty="easy",
- topic="化学安全与环保",
- content="下列做法中符合化学实验室安全要求的是:A.品尝药品判断其性质 B.用鼻子直接凑近药品闻气味 C.用手扇动少量气体再闻 D.把药品带回家继续做实验",
- answer_schema={
- "options": {
- "A": "品尝药品判断其性质",
- "B": "用鼻子直接凑近药品闻气味",
- "C": "用手扇动少量气体再闻",
- "D": "把药品带回家继续做实验",
- },
- "correct": ["C"],
- },
- hint="标准闻气体方法",
- ),
- ]
- # 补充自动生成的基础选择题示例,使 choice 题型接近 50 题
- base_choice_count = len(choice_data)
- for i in range(base_choice_count + 1, 51):
- choice_data.append(dict(
- difficulty="easy" if i <= 14 else "medium",
- topic="物质分类" if i % 2 == 0 else "酸碱盐",
- content=f"【选择题示例{i}】下列说法中正确的是?",
- answer_schema={
- "options": {
- "A": "这是一个占位示例选项 A",
- "B": "这是一个占位示例选项 B(正确)",
- "C": "这是一个占位示例选项 C",
- "D": "这是一个占位示例选项 D",
- },
- "correct": ["B"],
- },
- hint="用于系统演示的占位选择题,可后续替换为真实题目",
- ))
- for q in choice_data:
- questions.append(ChemistryQuestionBank(
- type="choice",
- difficulty=q["difficulty"],
- topic=q["topic"],
- content=q["content"],
- answer_schema=q["answer_schema"],
- hint=q.get("hint"),
- ))
- # 2. 化学方程式书写题(equation)约 50 题
- equation_data = [
- dict(
- difficulty="easy",
- topic="气体制取与性质",
- content="写出实验室用双氧水制氧气的化学方程式:",
- answer_schema={
- "expected_equation": "2H2O2 → 2H2O + O2↑",
- "conditions": "MnO2 作催化剂",
- },
- hint="注意配平和气体符号",
- ),
- dict(
- difficulty="easy",
- topic="金属及其化合物",
- content="写出铁在氧气中燃烧的化学方程式:",
- answer_schema={
- "expected_equation": "3Fe + 2O2 → Fe3O4",
- "conditions": "点燃",
- },
- hint="生成黑色固体 Fe3O4",
- ),
- dict(
- difficulty="easy",
- topic="气体制取与性质",
- content="写出碳酸钙与盐酸反应的化学方程式:",
- answer_schema={
- "expected_equation": "CaCO3 + 2HCl → CaCl2 + H2O + CO2↑",
- "conditions": "常温",
- },
- hint="实验室制备 CO2",
- ),
- dict(
- difficulty="easy",
- topic="酸碱盐",
- content="写出盐酸与氢氧化钠溶液反应的化学方程式:",
- answer_schema={
- "expected_equation": "HCl + NaOH → NaCl + H2O",
- "conditions": "溶液",
- },
- hint="典型中和反应",
- ),
- dict(
- difficulty="medium",
- topic="金属及其化合物",
- content="写出锌与稀盐酸反应的化学方程式:",
- answer_schema={
- "expected_equation": "Zn + 2HCl → ZnCl2 + H2↑",
- "conditions": "常温",
- },
- hint="金属与酸反应生成盐和氢气",
- ),
- dict(
- difficulty="medium",
- topic="金属及其化合物",
- content="写出铁与硫酸铜溶液反应的化学方程式:",
- answer_schema={
- "expected_equation": "Fe + CuSO4 → FeSO4 + Cu",
- "conditions": "常温",
- },
- hint="金属活动性顺序应用",
- ),
- dict(
- difficulty="medium",
- topic="酸碱盐",
- content="写出碳酸钠溶液与盐酸反应的化学方程式:",
- answer_schema={
- "expected_equation": "Na2CO3 + 2HCl → 2NaCl + H2O + CO2↑",
- "conditions": "溶液",
- },
- hint="注意 CO2 气体放出",
- ),
- dict(
- difficulty="medium",
- topic="酸碱盐",
- content="写出石灰水与二氧化碳反应的化学方程式:",
- answer_schema={
- "expected_equation": "Ca(OH)2 + CO2 → CaCO3↓ + H2O",
- "conditions": "微量 CO2",
- },
- hint="澄清石灰水变浑浊",
- ),
- ]
- # 补充自动生成的方程式题示例,使 equation 题型接近 50 题
- base_equation_count = len(equation_data)
- for i in range(base_equation_count + 1, 51):
- equation_data.append(dict(
- difficulty="easy" if i <= 14 else "medium",
- topic="化学方程式",
- content=f"【方程式示例{i}】写出一个常见的初中化学反应方程式:",
- answer_schema={
- "expected_equation": "示例:2H2 + O2 → 2H2O",
- "conditions": "可根据课堂情境自行设定",
- },
- hint="本题为占位示例,可后续替换为具体反应方程式",
- ))
- for q in equation_data:
- questions.append(ChemistryQuestionBank(
- type="equation",
- difficulty=q["difficulty"],
- topic=q["topic"],
- content=q["content"],
- answer_schema=q["answer_schema"],
- hint=q.get("hint"),
- ))
- # 3. 实验操作与安全常识题(experiment)约 50 题
- experiment_data = [
- dict(
- difficulty="easy",
- topic="化学实验基础",
- content="稀释浓硫酸的正确操作是?",
- answer_schema={
- "scenario": "稀释浓硫酸",
- "correct_operation": "将浓硫酸沿器壁慢慢倒入水中并不断搅拌",
- "key_point": "酸入水防飞溅",
- },
- hint="牢记“酸入水”原则",
- ),
- dict(
- difficulty="easy",
- topic="化学实验基础",
- content="检查装置气密性的常用方法是?",
- answer_schema={
- "scenario": "检查装置气密性",
- "correct_operation": "封闭系统后轻轻挤压或捂热容器,观察导管末端气泡变化",
- "key_point": "压强变化观察气泡",
- },
- hint="不能用明火直接检查",
- ),
- dict(
- difficulty="medium",
- topic="化学实验基础",
- content="蒸发结晶停止加热的合适时机是?",
- answer_schema={
- "scenario": "蒸发结晶",
- "correct_operation": "蒸发皿中出现大量晶体、溶液尚未全部蒸干时停止加热",
- "key_point": "防止暴沸和晶体飞溅",
- },
- hint="不能把水分完全蒸干",
- ),
- dict(
- difficulty="easy",
- topic="化学安全与环保",
- content="酒精灯着火后,应采用哪种方法灭火最安全?",
- answer_schema={
- "scenario": "酒精灯起火",
- "correct_operation": "用湿抹布或灯帽盖灭,隔绝空气",
- "key_point": "禁止向燃烧的灯内添加酒精",
- },
- hint="突出隔绝空气",
- ),
- dict(
- difficulty="easy",
- topic="化学安全与环保",
- content="强酸不慎溅到皮肤上,正确的处理方式是?",
- answer_schema={
- "scenario": "强酸溅到皮肤",
- "correct_operation": "立即用大量清水冲洗,再根据情况就医",
- "key_point": "大量清水冲洗稀释",
- },
- hint="不要先用碱液中和",
- ),
- dict(
- difficulty="medium",
- topic="化学实验基础",
- content="用量筒量取液体时,视线应如何放置?",
- answer_schema={
- "scenario": "量筒读数",
- "correct_operation": "视线与凹液面最低处所在水平线相平",
- "key_point": "避免视差",
- },
- hint="读弯月面最低点",
- ),
- dict(
- difficulty="medium",
- topic="化学实验基础",
- content="过滤操作中,滤纸应如何贴紧漏斗?",
- answer_schema={
- "scenario": "过滤",
- "correct_operation": "将滤纸润湿后贴紧漏斗内壁,过滤时液面低于滤纸边缘",
- "key_point": "防止液体从滤纸外流下",
- },
- hint="常见过滤规范",
- ),
- dict(
- difficulty="medium",
- topic="化学安全与环保",
- content="若不慎吸入较多氯气,正确的紧急处理方式是?",
- answer_schema={
- "scenario": "吸入有毒气体",
- "correct_operation": "迅速离开现场到空气新鲜处,必要时就医",
- "key_point": "远离气体来源并就医",
- },
- hint="强调撤离与就医",
- ),
- ]
- # 补充自动生成的实验与安全题示例,使 experiment 题型接近 50 题
- base_experiment_count = len(experiment_data)
- for i in range(base_experiment_count + 1, 51):
- experiment_data.append(dict(
- difficulty="easy" if i <= 14 else "medium",
- topic="化学实验基础" if i % 2 == 0 else "化学安全与环保",
- content=f"【实验与安全示例{i}】下列哪一项更符合规范的化学实验操作或安全要求?",
- answer_schema={
- "scenario": "实验室规范操作占位情境",
- "correct_operation": "选择符合课本要求的规范操作步骤",
- "key_point": "遵守实验室安全与操作规范",
- },
- hint="本题为占位示例,用于丰富题库数量,可后续替换为具体实验情境",
- ))
- for q in experiment_data:
- questions.append(ChemistryQuestionBank(
- type="experiment",
- difficulty=q["difficulty"],
- topic=q["topic"],
- content=q["content"],
- answer_schema=q["answer_schema"],
- hint=q.get("hint"),
- ))
- # 4. 计算类习题(calculation)约 50 题
- calculation_data = [
- dict(
- difficulty="medium",
- topic="溶液与浓度",
- content="将 20g 质量分数为 10% 的 NaCl 溶液稀释至 5%,需加水多少克?",
- answer_schema={
- "formula": "w = m溶质 / m溶液 × 100%",
- "steps": [
- "计算溶质质量:m溶质 = 20g × 10% = 2g",
- "设稀释后溶液质量为 m2,有 2 / m2 = 5% ⇒ m2 = 40g",
- "需加水质量 = 40g - 20g = 20g",
- ],
- "answer": 20.0,
- "unit": "g",
- },
- hint="注意溶质质量不变",
- ),
- dict(
- difficulty="medium",
- topic="气体制取与性质",
- content="电解 18g 水可制得氢气多少克?(相对分子质量:H2O=18,H2=2)",
- answer_schema={
- "formula": "2H2O → 2H2 + O2",
- "steps": [
- "由方程式知:36g 水生成 4g 氢气",
- "18g 水生成 x 克氢气,x = 4 × 18 / 36 = 2g",
- ],
- "answer": 2.0,
- "unit": "g",
- },
- hint="由化学方程式确定质量比",
- ),
- dict(
- difficulty="medium",
- topic="溶液与浓度",
- content="向 100g 质量分数为 5% 的 NaCl 溶液中加入 10g NaCl 固体,所得溶液的质量分数约为多少?",
- answer_schema={
- "formula": "w = m溶质 / m溶液 × 100%",
- "steps": [
- "原溶质质量:m1 = 100g × 5% = 5g",
- "加入溶质 10g,溶质总质量 m溶质 = 15g",
- "溶液总质量 m溶液 = 100g + 10g = 110g",
- "w ≈ 15 / 110 × 100% ≈ 13.6%",
- ],
- "answer": 13.6,
- "unit": "%",
- },
- hint="既改变分子也改变分母",
- ),
- dict(
- difficulty="medium",
- topic="溶液与浓度",
- content="配制 200g 质量分数为 10% 的 NaCl 溶液,需要 NaCl 和水各多少克?",
- answer_schema={
- "formula": "w = m溶质 / m溶液 × 100%",
- "steps": [
- "m溶质 = 200g × 10% = 20g",
- "m溶剂(水) = 200g - 20g = 180g",
- ],
- "answer": {"solute": 20.0, "solvent": 180.0},
- "unit": {"solute": "g", "solvent": "g"},
- },
- hint="先求溶质,再求溶剂",
- ),
- ]
- # 补充自动生成的计算题示例,使 calculation 题型接近 50 题
- base_calculation_count = len(calculation_data)
- for i in range(base_calculation_count + 1, 51):
- calculation_data.append(dict(
- difficulty="medium",
- topic="溶液与浓度" if i % 2 == 0 else "气体制取与性质",
- content=f"【计算题示例{i}】根据给出的相对分子质量和化学方程式,完成一题质量或质量分数计算。",
- answer_schema={
- "formula": "可结合题干给出的方程式与数据进行比例计算",
- "steps": [
- "写出对应的化学方程式并配平",
- "根据物质的量关系列出质量比或浓度表达式",
- "代入数据计算并保留合适有效数字",
- ],
- "answer": None,
- "unit": "",
- },
- hint="本题为占位示例,用于训练计算思路,可后续替换为具体数值题",
- ))
- for q in calculation_data:
- questions.append(ChemistryQuestionBank(
- type="calculation",
- difficulty=q["difficulty"],
- topic=q["topic"],
- content=q["content"],
- answer_schema=q["answer_schema"],
- hint=q.get("hint"),
- ))
- # 5. 物质推断题(inference)约 50 题
- inference_data = [
- dict(
- difficulty="medium",
- topic="金属及其化合物",
- content=(
- "A 为红色金属,B 能使澄清石灰水变浑浊,反应关系为:"
- "A + O₂ → B;B + Ca(OH)₂ → C。试推断 A、B、C 分别是什么物质?"
- ),
- answer_schema={
- "clues": "A 为红色金属;B 能使澄清石灰水变浑浊",
- "reaction_chain": "A + O2 → B; B + Ca(OH)2 → C",
- "answer": ["Cu", "CO2", "CaCO3"],
- },
- hint="结合颜色和使石灰水变浑浊的气体",
- ),
- dict(
- difficulty="medium",
- topic="金属及其化合物",
- content=(
- "X 与稀盐酸反应放出无色无味气体 Y,Y 能在空气中点燃呈淡蓝色火焰;"
- "金属 Z 能将 X 从其盐溶液中置换出来。试推断 X、Y、Z 分别可能是什么?"
- ),
- answer_schema={
- "clues": "X 与酸反应放氢气;Z 能置换 X",
- "reaction_chain": "X + 2HCl → XCl2 + H2↑; Z + XCl2 → ZCl2 + X",
- "answer": ["Zn", "H2", "Fe"],
- },
- hint="结合金属活动性顺序",
- ),
- dict(
- difficulty="medium",
- topic="酸碱盐",
- content=(
- "某白色固体 A 能溶于水,溶液能使紫色石蕊变红;"
- "A 溶液与一种无色溶液 B 反应生成白色沉淀 C。"
- "已知 B 中含有 Ba²⁺,推断 A、B、C 可能是什么?"
- ),
- answer_schema={
- "clues": "A 溶液显酸性;B 中含 Ba2+;生成白色沉淀",
- "reaction_chain": "2H+ + SO4(2-) + Ba2+ → BaSO4↓ + 2H+",
- "answer": ["H2SO4 或 NaHSO4 等酸性物质", "BaCl2 溶液", "BaSO4"],
- },
- hint="考虑生成难溶的硫酸钡沉淀",
- ),
- ]
- # 补充自动生成的物质推断题示例,使 inference 题型接近 50 题
- base_inference_count = len(inference_data)
- for i in range(base_inference_count + 1, 51):
- inference_data.append(dict(
- difficulty="medium",
- topic="金属及其化合物" if i % 2 == 0 else "酸碱盐",
- content=(
- f"【物质推断示例{i}】已知某些物质在反应中会生成气体或沉淀,"
- f"并且与金属活动性顺序或酸碱中和有关,请根据给出的线索推断相关物质。"
- ),
- answer_schema={
- "clues": "结合题干给出的颜色变化、气体放出或沉淀生成等信息",
- "reaction_chain": "围绕金属活动性顺序或酸碱中和建立推断链",
- "answer": [],
- },
- hint="本题为占位示例,用于训练推理链条,可后续替换为具体情境题",
- ))
- for q in inference_data:
- questions.append(ChemistryQuestionBank(
- type="inference",
- difficulty=q["difficulty"],
- topic=q["topic"],
- content=q["content"],
- answer_schema=q["answer_schema"],
- hint=q.get("hint"),
- ))
- # 6. 微观示意图分析题(diagram)约 50 题
- diagram_data = [
- dict(
- difficulty="easy",
- topic="微观粒子模型",
- content="下图为水分子分解示意图,该图可以解释哪一类化学变化?",
- answer_schema={
- "diagram_url": "img/molecule_H2O.png",
- "description": "水分子电解分解为氢气和氧气的微观示意",
- "analysis_question": "该图示可解释何种反应?",
- "key_insight": "水发生化学变化,分子分裂生成新物质",
- },
- hint="注意“分子分裂”为化学变化特征",
- ),
- dict(
- difficulty="easy",
- topic="微观粒子模型",
- content="下图为 NaCl 溶解电离的微观示意图,该溶液能导电的根本原因是?",
- answer_schema={
- "diagram_url": "img/ionization_NaCl.png",
- "description": "NaCl 晶体在水中电离为 Na⁺ 和 Cl⁻",
- "analysis_question": "为何溶液能导电?",
- "key_insight": "溶液中有大量可以自由移动的离子",
- },
- hint="区分金属导电与溶液导电机理",
- ),
- ]
- # 补充自动生成的微观示意图分析题示例,使 diagram 题型接近 50 题
- base_diagram_count = len(diagram_data)
- for i in range(base_diagram_count + 1, 51):
- diagram_data.append(dict(
- difficulty="easy" if i <= 14 else "medium",
- topic="微观粒子模型",
- content=f"【微观示意图示例{i}】根据给出的粒子示意图,判断该图反映的是物质状态变化、化学变化或电离过程之一。",
- answer_schema={
- "diagram_url": "img/example_micro_diagram.png",
- "description": "占位用微观粒子示意图,可表示分子间距、离子或原子的变化",
- "analysis_question": "图中反映的是哪一类微观变化?",
- "key_insight": "通过粒子种类、数目和排列方式的变化来判断物理或化学变化",
- },
- hint="本题为占位示例,可后续替换为具体教材中的微观粒子示意图",
- ))
- for q in diagram_data:
- questions.append(ChemistryQuestionBank(
- type="diagram",
- difficulty=q["difficulty"],
- topic=q["topic"],
- content=q["content"],
- answer_schema=q["answer_schema"],
- hint=q.get("hint"),
- ))
- db.session.bulk_save_objects(questions)
- db.session.commit()
- print("已向 chemistry_question_bank 插入 %d 道多题型习题" % len(questions))
- def seed_chemistry_hard_questions():
- """为多题型题库补充 hard 难度习题,每种题型不少于 10 道
- 已有的 hard 题会被保留,只在数量不足的题型上补齐到 10 道。
- """
- TARGET_COUNT = 10
- new_questions = []
- # 1. choice 题型:补足到 10 道 hard
- existing_choice = ChemistryQuestionBank.query.filter_by(
- difficulty="hard", type="choice"
- ).count()
- if existing_choice < TARGET_COUNT:
- for i in range(existing_choice + 1, TARGET_COUNT + 1):
- content = (
- f"【Hard 选择题 {i}】某反应前后有关物质的量或化合价发生变化,"
- f"下列说法中正确的是?"
- )
- answer_schema = {
- "options": {
- "A": "只要有气体生成就是氧化还原反应",
- "B": "只要有沉淀生成就是氧化还原反应",
- "C": "判断是否为氧化还原反应要看元素化合价是否变化",
- "D": "化学方程式两边原子个数不同也可能是氧化还原反应",
- },
- "correct": ["C"],
- }
- new_questions.append(ChemistryQuestionBank(
- type="choice",
- difficulty="hard",
- topic="化学方程式",
- content=content,
- answer_schema=answer_schema,
- hint="掌握氧化还原反应的本质:元素化合价发生变化",
- ))
- # 2. equation 题型:补足到 10 道 hard
- existing_equation = ChemistryQuestionBank.query.filter_by(
- difficulty="hard", type="equation"
- ).count()
- if existing_equation < TARGET_COUNT:
- for i in range(existing_equation + 1, TARGET_COUNT + 1):
- content = (
- f"【Hard 方程式 {i}】写出一个既体现金属活动性顺序,"
- f"又能体现沉淀生成的离子反应的配平化学方程式。"
- )
- answer_schema = {
- "expected_equation": "示例:Fe + CuSO4 → FeSO4 + Cu",
- "conditions": "常温,溶液中",
- }
- new_questions.append(ChemistryQuestionBank(
- type="equation",
- difficulty="hard",
- topic="化学方程式",
- content=content,
- answer_schema=answer_schema,
- hint="结合金属活动性顺序与难溶盐沉淀的知识,自拟一个合理的反应方程式",
- ))
- # 3. experiment 题型:补足到 10 道 hard
- existing_experiment = ChemistryQuestionBank.query.filter_by(
- difficulty="hard", type="experiment"
- ).count()
- if existing_experiment < TARGET_COUNT:
- for i in range(existing_experiment + 1, TARGET_COUNT + 1):
- content = (
- f"【Hard 实验与安全 {i}】在设计验证某气体为 CO2 的实验时,"
- f"如何合理选择试剂、装置并避免误判?"
- )
- answer_schema = {
- "scenario": "验证某无色气体是否为 CO2",
- "correct_operation": (
- "选用澄清石灰水检验,并设置对照实验;"
- "控制气体通入速度,防止生成 Ca(HCO3)2 造成再次澄清导致误判"
- ),
- "key_point": "有对照、控制变量,考虑条件变化对现象的影响",
- }
- new_questions.append(ChemistryQuestionBank(
- type="experiment",
- difficulty="hard",
- topic="化学实验基础",
- content=content,
- answer_schema=answer_schema,
- hint="思考如何通过对照与控制变量排除干扰因素",
- ))
- # 4. calculation 题型:补足到 10 道 hard
- existing_calculation = ChemistryQuestionBank.query.filter_by(
- difficulty="hard", type="calculation"
- ).count()
- if existing_calculation < TARGET_COUNT:
- for i in range(existing_calculation + 1, TARGET_COUNT + 1):
- content = (
- f"【Hard 计算题 {i}】某 100g NaCl 溶液,质量分数为 15%,"
- f"蒸发部分水并加入 10g NaCl 固体后,溶液质量分数变为 25%,"
- f"求蒸发水的质量。"
- )
- answer_schema = {
- "formula": "w = m溶质 / m溶液 × 100%",
- "steps": [
- "原溶质质量 m1 = 100g × 15% = 15g",
- "加入固体 NaCl 10g 后,溶质总质量 m溶质 = 25g",
- "设蒸发水质量为 x,则溶液终质量 m2 = 100 + 10 - x = 110 - x",
- "由 25 / (110 - x) × 100% = 25%,得 25 / (110 - x) = 0.25",
- "解得 110 - x = 100 ⇒ x = 10(g)",
- ],
- "answer": 10.0,
- "unit": "g",
- }
- new_questions.append(ChemistryQuestionBank(
- type="calculation",
- difficulty="hard",
- topic="溶液与浓度",
- content=content,
- answer_schema=answer_schema,
- hint="同时注意溶质和溶剂质量的变化,建立方程求解",
- ))
- # 5. inference 题型:补足到 10 道 hard
- existing_inference = ChemistryQuestionBank.query.filter_by(
- difficulty="hard", type="inference"
- ).count()
- if existing_inference < TARGET_COUNT:
- for i in range(existing_inference + 1, TARGET_COUNT + 1):
- content = (
- f"【Hard 物质推断 {i}】某白色固体 A 溶于水后溶液呈碱性,"
- f"与稀盐酸反应放出无色无味气体 B,B 能在空气中点燃呈淡蓝色火焰;"
- f"A 溶液与硫酸铜溶液反应生成蓝色沉淀 C。推断 A、B、C 分别是什么。"
- )
- answer_schema = {
- "clues": (
- "溶液呈碱性且与稀盐酸反应放出氢气;"
- "能与 CuSO4 生成蓝色沉淀"
- ),
- "reaction_chain": (
- "A + 2HCl → B↑ + 相应盐;"
- "A 溶液 + CuSO4 → C↓ + 其他产物"
- ),
- "answer": ["A:NaOH 或类似强碱", "B:H2", "C:Cu(OH)2"],
- }
- new_questions.append(ChemistryQuestionBank(
- type="inference",
- difficulty="hard",
- topic="酸碱盐",
- content=content,
- answer_schema=answer_schema,
- hint="结合气体性质和沉淀颜色,多步推断相关物质",
- ))
- # 6. diagram 题型:补足到 10 道 hard
- existing_diagram = ChemistryQuestionBank.query.filter_by(
- difficulty="hard", type="diagram"
- ).count()
- if existing_diagram < TARGET_COUNT:
- for i in range(existing_diagram + 1, TARGET_COUNT + 1):
- content = (
- f"【Hard 微观示意图 {i}】给出某反应前后微观粒子示意图:"
- f"反应前为双原子分子与单原子金属颗粒的混合,"
- f"反应后生成新的离子晶体。根据图示判断该反应类型并说明理由。"
- )
- answer_schema = {
- "diagram_url": "img/hard_example_micro_diagram.png",
- "description": "金属与酸或盐溶液反应生成新晶体和气体/离子的示意图",
- "analysis_question": "判断反应类型(置换、复分解等),并从微观角度解释",
- "key_insight": "从粒子种类和数目变化判断是否有新物质生成及反应类型",
- }
- new_questions.append(ChemistryQuestionBank(
- type="diagram",
- difficulty="hard",
- topic="微观粒子模型",
- content=content,
- answer_schema=answer_schema,
- hint="结合微观粒子变化与反应类型的宏观特征进行分析",
- ))
- if not new_questions:
- print("chemistry_question_bank 各题型的 hard 难度习题数量已达到或超过 10 道,跳过")
- return
- db.session.bulk_save_objects(new_questions)
- db.session.commit()
- print("已向 chemistry_question_bank 追加 %d 道 hard 难度习题" % len(new_questions))
- def seed_knowledge_points():
- """从题目与知识图谱中同步知识点到 knowledge_points 表"""
- if KnowledgePoint.query.first():
- return
- names = set()
- for (kp,) in db.session.query(Question.knowledge_point).filter(
- Question.knowledge_point.isnot(None),
- Question.knowledge_point != "",
- ).distinct().all():
- if kp:
- names.add(kp)
- for s, p, o in [
- ("电解质", "定义", "在水溶液或熔融状态下能够导电的化合物"),
- ("氧化还原反应", "特征", "有元素化合价发生变化的反应"),
- ("物质的量", "单位", "mol(摩尔)"),
- ("原子", "结构", "原子核和核外电子"),
- ]:
- names.add(s)
- if isinstance(o, str):
- names.add(o)
- for name in names:
- if not KnowledgePoint.query.filter_by(name=name).first():
- db.session.add(KnowledgePoint(name=name))
- db.session.commit()
- print("已同步 %d 个知识点到 knowledge_points" % len(names))
- def seed_knowledge_graph():
- """初中化学知识图谱三元组"""
- if KnowledgeRelation.query.first():
- print("知识图谱已有数据,跳过")
- return
- data = [
- ("电解质", "定义", "在水溶液或熔融状态下能够导电的化合物"),
- ("电解质", "包含", "酸、碱、盐"),
- ("非电解质", "定义", "在水溶液和熔融状态下都不导电的化合物"),
- ("非电解质", "举例", "蔗糖、酒精"),
- ("氧化还原反应", "特征", "有元素化合价发生变化的反应"),
- ("氧化还原反应", "包含", "氧化反应和还原反应"),
- ("物质的量", "单位", "mol(摩尔)"),
- ("物质的量", "表示", "含有一定数目粒子的集合体"),
- ("元素周期律", "内容", "元素的性质随原子序数递增呈周期性变化"),
- ("元素周期律", "表现", "原子半径、金属性、非金属性等"),
- ("离子反应", "条件", "有沉淀、气体或弱电解质生成"),
- ("化学反应速率", "定义", "单位时间内反应物或生成物浓度的变化"),
- ("催化剂", "特点", "能改变化学反应速率而本身质量和化学性质不变"),
- ("原子", "结构", "原子核和核外电子"),
- ("原子核", "组成", "质子和中子"),
- ]
- for s, p, o in data:
- db.session.add(KnowledgeRelation(subject=s, predicate=p, obj=o))
- db.session.commit()
- print("已插入 %d 条知识图谱三元组" % len(data))
- def main():
- with app.app_context():
- seed_questions()
- seed_knowledge_graph()
- seed_knowledge_points()
- seed_curriculum_topics()
- seed_chemistry_question_bank()
- seed_chemistry_hard_questions()
- print("初始化完成")
- if __name__ == "__main__":
- main()
|