我用AI开发了一个材料查询工具,发到了PyPI上

一个材料科学家的编程成长故事
前言
我是材料科学领域的研究人员,日常工作中经常需要查询 Materials Project 数据库中的材料信息。
某天,我对AI说:
“帮我写一个程序,能查询材料、显示带隙、下载CIF文件”
AI几分钟就写出了代码。我又陆续提出新需求,AI逐一实现。就这样,一个完整的材料查询工具诞生了。
今天,我想把这个开发过程分享给你。
项目简介
Materials Viewer – Materials Project 材料查询工具
-
• 技术栈:Python + Tkinter + pymatgen -
• 核心功能:化学式查询 → 筛选 → 下载CIF/POSCAR → 3D可视化 -
• 发布平台:PyPI(任何人可以用 pip install materials-viewer-mp安装)
一、从0到1:快速实现基础功能
1.1 我的第一个需求
帮我写一个程序,能根据化学式查询Materials Project数据库的材料信息
AI立刻生成了带图形界面的程序:
-
• 输入化学式(如 BaTiO3) -
• 显示材料ID、能量、带隙等 -
• 点击下载 CIF 文件
关键代码:
def search(self): formula = self.e.get() with MPRester(api_key) as m: results = m.query(formula, properties=[...]) # 显示在表格中
1.2 让用户保存设置
"用户设置VESTA路径后,要保存,下次打开程序时能正常工作""用户输入API Key后,也需要保存"
实现方案:
-
• 配置文件存储在用户主目录 ~/.materials_viewer/ -
• 使用 JSON 格式保存 -
• API Key 用 Base64 简单加密
import jsonfrom pathlib import Pathconfig_dir = Path.home() / ".materials_viewer"config_file = config_dir / "config.json"def save_config(self): config = { "vesta_path": self.vesta_path, "api_key": self._encrypt(self.api_key) # 加密存储 } config_file.write_text(json.dumps(config))
二、渐进增强:每次只做一件事
2.1 添加筛选功能
"带隙一列,能不能加个筛选范围?"
def apply_filter(self): min_gap = float(self.gap_min.get()) max_gap = float(self.gap_max.get()) for item in self.results: if min_gap <= item['band_gap'] <= max_gap: # 显示
2.2 添加排序功能
"能不能按带隙排序?"
点击表头即可排序:
def on_header_click(self, col): self.data.sort(key=lambda x: x[col], reverse=self.reverse) self.reverse = not self.reverse
2.3 优化输入体验
"输入化学式后,能不能直接回车查询?"
一行代码搞定:
self.e.bind("<Return>", lambda event: self.search())
2.4 空间群显示序号
"空间群能不能显示序号?比如 P4mm (99)"
# 获取数据时d['sg'] = structure.get_space_group_info()[0] # P4mmd['sg_num'] = structure.get_space_group_info()[1] # 99# 显示时sg_display = f"{sg} ({sg_num})" if sg_num else sg
2.5 添加空间群筛选
"能不能按空间群筛选?比如输入 99"
模糊匹配,支持符号或序号:
if sg_filter: if sg_filter.lower() not in sg_symbol.lower() and sg_filter != sg_num: continue # 不符合筛选条件
三、工程化改造:让代码更健壮
3.1 提取常量
问题:代码里到处是 900x650、100、10 这样的数字
# 优化前self.root.geometry("900x650")# 优化后class App: WINDOW_SIZE = "900x650" DEFAULT_GAP_MIN = 0.05 DEFAULT_GAP_MAX = 10.0
好处:修改一处,所有地方都生效
3.2 添加日志
程序出问题了?加日志:
import logginglogging.basicConfig( level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s', handlers=[ logging.FileHandler('app.log'), logging.StreamHandler() ])logger = logging.getLogger(__name__)logger.info(f"查询材料: {formula}")logger.error(f"查询失败: {error}")
3.3 临时文件管理
下载的文件先存临时目录,程序退出时清理:
import tempfileimport atexitself.temp_file = tempfile.mktemp(suffix='.cif')atexit.register(lambda: os.unlink(self.temp_file) if os.path.exists(self.temp_file))
3.4 输入验证
import redef validate_formula(self, formula): pattern = r'^([A-Z][a-z]?\d*)+$' # BaTiO3, H2O, Fe2O3 if not re.match(pattern, formula): messagebox.showwarning("提示", "请输入有效的化学式") return False return True
四、功能迭代完整记录
|
|
|
|
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
总计:15个版本,15个功能,全部来自实际需求
五、发布到PyPI
PyPI是Python包的”应用商店”,发布后任何人都能用pip安装。
5.1 准备发布文件
materials-viewer/├── setup.py # 安装配置├── pyproject.toml # 构建配置├── README.md # 项目说明├── LICENSE # MIT许可证└── materials_viewer/ # 源代码 ├── __init__.py ├── cli.py └── mv.py
5.2 配置入口点
# setup.pyentry_points={ 'console_scripts': [ 'mv=materials_viewer.cli:main', # 安装后输入'mv'即可运行 ],},
5.3 构建和上传
# 1. 安装构建工具pip install build twine# 2. 构建python -m build# 3. 上传到PyPItwine upload dist/*
5.4 用户安装使用
# 安装pip install materials-viewer-mp# 运行mv
六、AI编程心得
6.1 分步骤提出需求
❌ 一次说太多:帮我写一个完整的材料查询工具✅ 逐步提出:先实现查询 → 再加下载 → 再加筛选
6.2 具体描述问题
❌ 不起作用✅ 点击下载没反应,看日志是权限错误,需要处理
6.3 让AI解释代码
"这段代码是什么意思?""有没有更好的实现方式?"
6.4 及时测试
每实现一个功能,立刻测试。发现bug,立刻让AI修复。
七、代码质量提升路径
|
|
|
|
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
结语
用AI编程,不是”AI写代码我用”,而是”我和AI一起解决问题”。
我的经验是:
-
1. 从小需求开始,逐步扩展 -
2. 每个功能测试,确保可用 -
3. 保持代码整洁,方便维护 -
4. 发布到PyPI,让更多人使用
附录
项目地址:https://github.com/haiw201/materials-viewer
PyPI地址:https://pypi.org/project/materials-viewer-mp/
安装命令:
pip install materials-viewer-mp
感谢阅读!如果对你有帮助,欢迎转发分享!
夜雨聆风