当前位置:首页>python>Python实际项目——离子可溶性检测器

Python实际项目——离子可溶性检测器

  • 2026-08-22 21:51:33
Python实际项目——离子可溶性检测器
众所周知,九年级下册化学一个非常难的单元就是酸碱盐,而酸碱盐中又有一个板块叫做复分解反应,复分解反应成立的条件是生成物之中要么有水,要么有沉淀,要么有气体生成。
而在实际学习过程中,就经常有一个问题:这东西可不可溶?如果可溶,那么不是沉淀,如果不可溶就是沉淀。
从化学课外班老师那里要来一张口诀表:

初中五酸皆可溶

碱溶钾钠钡钙铵

盐酸盐不溶银亚汞

硫酸盐不溶钡和铅

碳酸盐只溶钾钠铵

硝酸盐一切皆可溶

碳酸氢盐皆可溶

化学老师
这口诀……难背。能不能写个程序,输入物质的化学式,自动输出它的溶解性?
说干就干。本质上,酸碱盐都是由离子组成的。准备工作:先定义好三个类,分别表示离子,阳离子,阴离子
然后是第二步:接受用户输入,并从用户输入中分离出阳离子和阴离子
根据化学知识我们知道,阳离子写在前面,阴离子写在后面。以H2SO4为例,“H”是它的阳离子,“SO4”是它的阴离子。Python中,str对象有startswith和endswith方法用于判断一个字符串开头/结尾是否为指定的子字符串,返回True(是)或False(不是)
阳离子分离相对简单,代码如下:
而阴离子分离相对复杂一点:比如Fe(OH)3,后面跟了个3,然后中间还有括号,难以提取出“OH”。
我们可以先用字符串的replace方法,将括号删除。然后判断最后一位是否为数字,如果是数字,那么删掉最后一位。
但是这样还是有问题,比如NH4NO3,按照这样的规则,会提取到阴离子为“NO”,这显然不是我们期望的结果
我们可以这样:先尝试不删数字,直接提取。如果直接提取失败,那么再尝试删数字
好了,让我们来试一下这个函数。我们测试四个案例:氢氧化铁,盐酸,硫酸,硝酸铵
ok,全部正确
好了,第三步:对口诀。既然已经拿到阳离子和阴离子了,直接往开头口诀那里代入即可
最后再把主程序写一下就算完工~
好了,那么这个程序总共花费122行,完工~
接下来,优化一下代码。我们看看Lon,Anion,Cation这三个类,给我们带来了大量的转换麻烦,但是又没有什么用。离子直接用字符串表示貌似也可以。现在又暂时不用考虑化合价的影响,干脆删了吧
最终,经过优化后。代码只剩106行了。说实话现在挺感慨的,竟然106行就可以把这个看起来复杂的功能优雅的完成(非打表)
源代码展示:
all_cation=["H","Ag","K","Ba","NH4","Na","Hg",                "Pb","Ca","Fe","Cu","Mg","Al","Zn"]all_anion=["SO4","Cl","NO3","HCO3",# HCO3-:碳酸氢根离子            "OH","CO3"]strip_char=list("()[]{}<>《》()")def get_input(pmt):    initial_input=input(pmt)    for char in strip_char:        initial_input=\                initial_input.replace(char,"")# 删除指定字符    for i in all_cation:        if initial_input.startswith(i):            cation=i            break    else:        raise Exception("unknown cation")    for i in all_anion:        if initial_input.endswith(i):            anion=i            break    else:# 循环正常结束,没有找到阴离子        # 判断最后一位是否为数字        try:            int(initial_input[-1])        except ValueError:            raise Exception("unknown anion")        else:            filter_input=initial_input[:-1]# 删去最后一位数字,再次尝试            for i in all_anion:                if filter_input.endswith(i):                    anion=i                    break            else:                raise Exception("unknown anion")    return cation,aniondef judg(cation:str,anion:str) -> bool:    # 初中五酸皆可溶    if cation=="H":        if anion in ["SO4","Cl","NO3","CO3","HCO3"]:            return True        else:            # 这个化学式根本不存在(HFe)?            return False    # 碱溶钾钠钡钙铵    elif anion=="OH":        if cation in ["Ca","Na","Ba","K","NH4"]:            return True        else:return False    # 硝酸盐一切皆可溶    elif anion=="NO3":        return True    # 盐酸盐不溶银亚汞    # 亚汞初中不考    elif anion=="Cl":        if cation in ["Ag","Hg"]:            return False        else:return True    # 硫酸盐不溶钡和铅    elif anion=="SO4":        if cation in ["Ba","Pb"]:            return False        else:return True    # 碳酸盐只溶钾钠铵    elif anion=="CO3":        if cation in ["K","Na","NH4"]:            return True        else:return False    # 碳酸氢盐皆可溶    elif anion=="HCO3":        return True    else:        # 我们已经枚举了所有情况,理论上不应该有样例能到达这里        # 程序出错,储存错误后退出        with open("coredump.txt","a") as f:            f.write(f"cation:{cation}\nanion:{anion}\n\n")        raise Exception("unexcepted case.Send the coredump.txt to me.")print("输入物质化学式(如:Fe2(SO4)3)以检测可溶性")print("括号不加也可以,数字无需加下标!")print("作者:马千程。祝您使用愉快~")while True:    try:        data=get_input(pmt="请输入化学式")        result=judg(*data)        if result: print("该物质可溶!")        else: print("该物质不可溶!")    except Exception:        try:            import traceback        except ImportError:# 极端情况:标准库导入失败!            print("抱歉!程序出现严重错误,请将您的输入截图发送给我")        else:            print("抱歉!程序出现错误!请将以下信息发送给我!")            error_msg = traceback.format_exc()            print(error_msg)
最后,让我们把这个程序打包,送给化学老师吧~
好了,本篇文章就到这里,感谢大家观看,再见

最新文章

随机文章