zoukankan      html  css  js  c++  java
  • 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

    参考资料

  • 相关阅读:
    Entity Framework Core 2.0 新特性
    asp.net core部署时自定义监听端口,提高部署的灵活性
    asp.net core使用jexus部署在linux无法正确 获取远程ip的解决办法
    使用xshell连接服务器,数字键盘无法使用解决办法
    使用Jexus 5.8.2在Centos下部署运行Asp.net core
    【DevOps】DevOps成功的八大炫酷工具
    【Network】Calico, Flannel, Weave and Docker Overlay Network 各种网络模型之间的区别
    【Network】UDP 大包怎么发? MTU怎么设置?
    【Network】高性能 UDP 应该怎么做?
    【Network】golang 容器项目 flannel/UDP相关资料
  • 原文地址:https://www.cnblogs.com/peterlddlym/p/12680449.html
Copyright © 2011-2022 走看看