20181202 实验二《Python程序设计》实验报告
20181202 2019-2020-2 《Python程序设计》实验二报告
课程:《Python程序设计》
班级: 1812
姓名: 李祎铭
学号:20181202
实验教师:王志强
实验日期:2020年4月11日
必修/选修: 公选课
1.实验内容
-
设计并完成一个完整的应用程序,完成加减乘除摸等运算,功能多多益善。
-
考核基本语法、判定语句、循环语句、逻辑运算等知识点
2. 实验过程及结果
2.1 设计思路
- 此计算器设计为可以通过分析数学公式,进行具有一定复杂度的数学运算
- 主要使用正则表达式对数学公式进行分解,按照运算优先度进行运算,应用判定语句、循环语句等知识计算出数学算式的结果
- 先计算()中的内容,按照幂运算**,乘除运算*/,加减运算+-的顺序依次进行计算
2.2 实验过程
- 幂运算函数
def power(f):
ret = re.split('\*\*',f)
if len(ret) == 2:
f=str(float(ret[0])**float(ret[1]))
return f
- 乘法运算
def mul_div(f):
ret = re.split(r'([*/])',f)
if len(ret) == 3:
if(ret[1] == '*'):
f=str(float(ret[0])*float(ret[2]))
else:
f=str(float(ret[0])/float(ret[2]))
return f
- 加减运算
def add_sub(f):
ret = re.spilt('([+-])',f)
if(len(ret)==3):
if ret[1] == '+':
f=str(float(ret[0])+float(ret[2]))
else:
f=str(float(ret[0])-float(ret[2]))
return f
- 无括号运算
def no_bra(fa):
while True:#幂运算
ret = re.spilt('(\d+\.?\d*\*\*\d+\.?\d*)',fa,1)
if(len(ret) == 3):
ret[1] = power(ret[1])
fa = ret[0]+ret[1]+ret[2]
continue
else:
break
while True:#乘除运算
ret = re.spilt('(\d+\.?\d*[*/]\d+\.?\d*)',fa,1)
if(len(ret)==3):
ret[1] = mul_div(ret[1])
fa = re[0]+ret[1]+ret[2]
continue
else:
break
while True:#加减运算
if(fa == re.match('[-+]?\d+\.?\d*',fa)):
break
else:
ret = re.spilt('(\d+\.?\d*)',fa,2)
if(len(ret)==5):
if(ret[0]==ret[2] or (ret[0]== '' and ret[2]=='+'):
fa = str(ret[0] + add_sub(ret[1] + '+' + ret[3]) + ret[4])
else:
fa = str(ret[0] + add_sub(ret[1] + '-' + ret[3]) + ret[4])
continue
else:
break
return fa
- 主函数
def main(fa):
while True:
ret = re.split('\(([^()]+)\)',fa,1)
if (len(ret)==3):
ret[1]=str(no_bra(ret[1]))
fa = ret[0]+ret[1]+ret[2]
continue
else:
break
return no_bra(fa)
- 错误检测
def checkFalse(fa):
list = ['+', '-', '*', '/']
count_1 = 0
count_2 = 0
for i in fa:
if(i == '('):
count_1 += 1
elif(i == ')'):
count_2 += 1
elif (i == ' '):
print("不能包含空格")
os._exit(-1)
if(count_1 != count_2):
print("括号不匹配!")
os._exit(-1)
for j in range(0, len(fa)-1):
if((fa[j] in list) and (fa[j + 1] in list)):
if((fa[j] == '*') and (fa[j + 1] == '*')):
print("ok")
else:
print("数学公式不符合运算规则!")
os._exit(-1)
return main(fa)
2.3 实验结果
3. 实验过程中遇到的问题和解决过程
- 问题1:在编写checkFalse(fa)函数时,我首先使用的是:
for j in range(0,len(fa)):
if((fa[j] in list) and (fa[j+1] in list)):
print("数学公式不符合运算规则!")
os._exit(-1)
但这会使原本的幂运算同样被认定为不合逻辑,经过修改,添加判断条件,得出解决方案
- 问题1解决方案:
for j in range(0,len(fa)-1):
if((fa[j] in list) and (fa[j+1] in list)):#添加判断条件
if(fa[j]=='*' and fa[j+1] =='*'):
continue
else:
print("数学公式不符合运算规则!")
os._exit(-1)
- 问题2:在程序执行完checkFalse(fa)函数后,便不再继续向下进行,使用pysnooper对no_bra(fa)函数进行监视,发现如下情况
- 问题2解决方案:从图中可以看出,语句陷入死循环,检查后发现原来是将赋值语句误写为了"=="
- ...
其他
一点点心得
我认为在完成过程中最重要的一个问题就是搞懂re.split的用法,以及选取不同的分割次数来匹配不同的计算问题。此外,在实际操作过程中还出现了一些细节问题,比如我的问题2,问题很简单,但不好发现,这个时候就需要充分利用断点调试,在经过使用pysnooper对函数进行单独检测后便可以比较轻易的找到问题。
源码
这个公式计算器程序,是我在现有基础上加入错误检查功能后修改而成的,源码如下:
[码云]:https://gitee.com/li_ming_XXL/to_learn_python/blob/master/test_2.py