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 实验结果

alt 成果截图

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)函数进行监视,发现如下情况
    alt 问题
  • 问题2解决方案:从图中可以看出,语句陷入死循环,检查后发现原来是将赋值语句误写为了"=="
    alt 解决
  • ...

其他

一点点心得

我认为在完成过程中最重要的一个问题就是搞懂re.split的用法,以及选取不同的分割次数来匹配不同的计算问题。此外,在实际操作过程中还出现了一些细节问题,比如我的问题2,问题很简单,但不好发现,这个时候就需要充分利用断点调试,在经过使用pysnooper对函数进行单独检测后便可以比较轻易的找到问题。

源码

这个公式计算器程序,是我在现有基础上加入错误检查功能后修改而成的,源码如下:
[码云]:https://gitee.com/li_ming_XXL/to_learn_python/blob/master/test_2.py

参考资料

posted @ 2020-04-11 15:54  1202李祎铭  阅读(186)  评论(0编辑  收藏  举报