从《诗经•蒹葭》谈一下python的脚本写法之bug篇

2018-05-12


前面我们写了个检查任务收敛的脚本。但那只是个初级的版本,也就是存在bug。通过下面几个例子,我们学习一下bug的产生原因,解决,以及注意的部分。


例子1:如果你的任务没有收敛,使用脚本的时候,会得到这样的错误。

 


看一下错误的提示,在脚本中的 return int(nsw_out)行,获取OSZICAR中计算的步数时,出错了。首先,我们先搞明白一下这个版本中获取OSZICAR计算步骤的原理。



1)  前提,你的任务已经完成。此时,OSZICAR的最后一行的第一个数就是我们计算所用的步数。如下图。

 

 

所以,脚本用到: data_in.readlines()[-1].rstrip().split()[0]  来获取最后一行的第一个数。代码里面的[-1]代表OSZICAR文件的最后一行。

 



2)  如果你的任务没有算完,则OSZICAR是下面图中的这个样子, 也就是最后一行的第一个 ”数”是个字母, 因此,当你运行脚本的时候,会出错,因为int()这个用来将字符串转化为整数,而字母是不能被转化为整数的。





3)    解决办法


分析OSZICAR,你会发现,每个离子步的最后一行都有一个 F= 。我们可以通过这个关键词来获取前面的数值。


 

继续延续《蒹葭》里面的思路:保持框架,只变动某个字母。

我们建一个列表nsw_l ,通过F= 这个关键词,将它前面所有的数值都存到列表里面,然后定义的函数只返回最后一个数值即可。int(nsw_l[-1])



这样的话,不管任务是在进行中,或者是结束,都可以正常运行脚本了。



 

例子2:


同样来自于用户的反馈,与上面不同的是,该用户习惯在INCAR的参数后面加一些详细的说明。比如: 


NSW = 200  max number of geometry steps


如果你是这样子写的INCAR,使用脚本依然会出错。(大家自己试试)


1)  我们看一下获取INCAR中NSW数值的方法。



首先我们通过NSW这个关键词定义到所在的行,然后通过等号 "=" 作为分割符,将NSW = 200 分割成 'NSW' 和'200',并存在一个列表里面。如果你的NSW = 200 后还加了其他说明的话,那么列表里面的内容就变成了'NSW'和  '200  max number of geometry steps' (200和后面的一堆是一个整体。) 所以,当你将它转化成数字的时候,就会同样出错。

 



下面我们做几个测试的例子。

 


 

当我们在NSW = 200 后面添加说明后,

 


脚本运行出错了。因为没有办法把‘200 Max number for geometry steps’ 这个字符串 转化为整数。

 



那么我们改怎么做呢?


目前我们得到了‘200 Max number for geometry steps’ 这个字符串,剩下的就是获取字符串中的200了。可以使用空格将这个字符串继续分割。在[1]后面加上 .split()[0]

 

 

到现在,这个问题也得到解决了。

 



例子3:

 

1)       INCAR 中如果写了好多行有关NSW的参数呢? 比如下面的这种。

# NSW = 1 

# NSW = 200

 NSW = 200 Max number

 

2)  如果你的任务刚刚提交,一个离子步都没有算完,你就运行脚本检查了。

 

以上两种情况,都会导致错误的产生。大家可以试试。解决办法,本文就不再详细啰嗦了。

这里大师兄表达的是:

1)对于INCAR,由于不同的人有着不同的写法,而脚本也会发生相应的变化。

2)而且计算的不同阶段运行脚本也会出错。

所以,脚本很强大, 但也很脆弱。


当你从别人那里获取一个脚本后,一定要知道里面的原理以及需要注意的地方。而实际情况是,很多人不懂程序语言,拿到脚本就直接用,得到错误的结果不知道。运行错了,也不会解决。这个时候我的建议是:在使用脚本前,应该保证自己有一个保底的解决办法。这样的话,两者可以相互印证。另一个建议就是:使用一些大众化的,大家经常用的脚本,比如VTST,王老师的vaspkit等。这些脚本一方面可靠性高(结果有保证),另一方面用的人比较多,出错了也很容易解决。(运行出错有保证)。




打赏一下,鼓励大师兄们写出更好的文章!



本网站由阿里云提供云计算及安全服务