zoukankan      html  css  js  c++  java
  • 180119 计算器的优化版

    print("33[31;1m欢迎使用计算器33[0m".center(59,"-"))
    import sys,time #导入模块 sys模块,time模块
    
    f = open("intro.txt",'r') #打开文件 同一个目录里的名为“intro”的文件,打开为读取
    
    for line in f:  #循环读取刚刚打开的f的行line; for...in... 循环 ;for..in语句是个循环语句,它迭代一个对象的序列,现在,你需要知道的是一个序列只是一个有序的项目的集合。
        for i in line: #循环读取文字;读取上一行读取的行line里的每个文字,生成列表i
            sys.stdout.write(i) #标准输出 这就是导入sys模块的原因,用到其中的stdout.write,后面跟上(i)——标准输出上一行的文字列表i
            sys.stdout.flush() #刷新 这是间隔一段时间刷新的意思,sys.stdout        .flush ...
            time.sleep(0.05) #输出时间控制  再次看到time模块的.sleep ,参数设定为(0.1)秒
    import re,os,sys  #导入 re os sys 模块 具体运用到的功能详解。
    
    def compute_exponent(arg):  #定义一个函数 指数计算  ps() 里的arg 前几天的博文里有记录作用和含义
        """ 操作指数
        :param expression:表达式
        :return:计算结果
        """
    
        val = arg[0]  #声明一个变量 val = arg   ps.列表是零
        pattern = re.compile(r'd+.?d*[*]{2}[+-]?d+.?d*')    #有点复杂了,起码用上了re.compile 正则表达式……
        mch = pattern.search(val)    # 不太懂了!!
        if not mch:
            return
        content = pattern.search(val).group()
    
        if len(content.split('**'))>1:
            n1, n2 = content.split('**')
            value = float(n1) ** float(n2)
        else:
            pass
    
        before, after = pattern.split(val, 1)
        new_str = "%s%s%s" % (before,value,after)
        arg[0] = new_str
        compute_exponent(arg)
    
    def compute_mul_div(arg):
        """ 操作乘除
        :param expression:表达式
        :return:计算结果
        """
    
        val = arg[0]
        pattern = re.compile(r'd+.?d*[*/\%//]+[+-]?d+.*d*')
        mch = pattern.search(val)
        if not mch:
            return
        content = pattern.search(val).group()
    
        if len(content.split('*'))>1:
            n1, n2 = content.split('*')
            value = float(n1) * float(n2)
        elif len(content.split('//'))>1:
            n1, n2 = content.split('//')
            value = float(n1) // float(n2)
        elif len(content.split('%'))>1:
            n1, n2 = content.split('%')
            value = float(n1) % float(n2)
        elif len(content.split('/'))>1:
            n1, n2 = content.split('/')
            value = float(n1) / float(n2)
        else:
            pass
    
        before, after = pattern.split(val, 1)
        new_str = "%s%s%s" % (before,value,after)
        arg[0] = new_str
        compute_mul_div(arg)
    
    
    def compute_add_sub(arg):
        """ 操作加减
        :param expression:表达式
        :return:计算结果
        """
        while True:
            if arg[0].__contains__('+-') or arg[0].__contains__("++") or arg[0].__contains__('-+') or arg[0].__contains__("--"):
                arg[0] = arg[0].replace('+-','-')
                arg[0] = arg[0].replace('++','+')
                arg[0] = arg[0].replace('-+','-')
                arg[0] = arg[0].replace('--','+')
            else:
                break
    
    
        if arg[0].startswith('-'):
    
            arg[1] += 1
            arg[0] = arg[0].replace('-','&')
            arg[0] = arg[0].replace('+','-')
            arg[0] = arg[0].replace('&','+')
            arg[0] = arg[0][1:]
        val = arg[0]
    
        pattern = re.compile(r'd+.?d*[+-]{1}d+.?d*')
        mch = pattern.search(val)
        if not mch:
            return
        content = pattern.search(val).group()
        if len(content.split('+'))>1:
            n1, n2 = content.split('+')
            value = float(n1) + float(n2)
        else:
            n1, n2 = content.split('-')
            value = float(n1) - float(n2)
    
        before, after = pattern.split(val, 1)
        new_str = "%s%s%s" % (before,value,after)
        arg[0] = new_str
        compute_add_sub(arg)
    
    
    def compute(expression):
        """ 操作加减乘除
        :param expression:表达式
        :return:计算结果
        """
        inp = [expression,0]
    
        # 处理表达式中的指数
        compute_exponent(inp)
    
        # 处理表达式中的乘除求余等
        compute_mul_div(inp)
    
        # 处理表达式的加减
        compute_add_sub(inp)
        if divmod(inp[1],2)[1] == 1:
            result = float(inp[0])
            result = result * -1
        else:
            result = float(inp[0])
        return result
    
    
    def exec_bracket(expression):
        """ 递归处理括号,并计算
        :param expression: 表达式
        :return:最终计算结果
        """
        pattern = re.compile(r'(([+-*/\%//**]*d+.*d*){2,})')
        # 如果表达式中已经没有括号,则直接调用负责计算的函数,将表达式结果返回,如:2*1-82+444
        #if not re.search('(([+-*/]*d+.*d*){2,})', expression):
        if not pattern.search(expression):
            final = compute(expression)
            return final
        # 获取 第一个 只含有 数字/小数 和 操作符 的括号
        # 如:
        #    ['1-2*((60-30+(-40.0/5)*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))']
        #    找出:(-40.0/5)
        content = pattern.search(expression).group()
    
    
        # 分割表达式,即:
        # 将['1-2*((60-30+(-40.0/5)*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))']
        # 分割更三部分:['1-2*((60-30+(    (-40.0/5)      *(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))']
        before, nothing, after = pattern.split(expression, 1)
    
        print('分解中:',expression)
        content = content[1:len(content)-1]
    
        # 计算,提取的表示 (-40.0/5),并活的结果,即:-40.0/5=-8.0
        ret = compute(content)
    
        print('%s=%s' %( content, ret))
    
        # 将执行结果拼接,['1-2*((60-30+(      -8.0     *(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))']
        expression = "%s%s%s" %(before, ret, after)
        print('下一步:',expression)
        print("~"*10,'按优先级运算ing...',"~"*10)
    
        # 循环继续下次括号处理操作,本次携带者的是已被处理后的表达式,即:
        # ['1-2*((60-30+   -8.0  *(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))']
    
        # 如此周而复始的操作,直到表达式中不再含有括号
        return exec_bracket(expression)
    
    
    
    # 使用 __name__ 的目的:
    #   只有执行 python index.py 时,以下代码才执行
    #   如果其他人导入该模块,以下代码不执行
    if __name__ == "__main__":
        flag = True
    
    
    
    
        while flag:
            calculate_input = input('33[43m请输入要计算的算式 | (退出请按q)33[0m')
            calculate_input = re.sub('s*','',calculate_input)
            if len(calculate_input) == 0:
                continue
            elif calculate_input == 'q':
                print("欢迎使用,再见!".center(48, "-"))
                exit()
            elif re.search('[^0-9.-+*/\%//**()]',calculate_input):
                print('33[31m 输入错误,请重新输入!!!33[0m')
            else:
                result = exec_bracket(calculate_input)
                print('33[31m最终的计算结果是: %s33[0m' % result)

    好吧,这段代码比较长,而且个人感觉还不够完美,只解析了括号内的运算

  • 相关阅读:
    冒泡排序
    linux常用命令
    Github上将公共仓库转为私有仓库or私有仓库转为共有仓库
    使用apt更新和升级系统软件
    Django用户认证模块中继承AbstractUser与AbstractBaseUser重写User表的区别
    详解django中的collectstatic命令以及STATIC_URL、STATIC_ROOT配置
    python入门指南
    python包装不上?国内网络问题,使用豆瓣源解决
    nginx入门
    Vue 实现页面刷新(provide 和 inject)
  • 原文地址:https://www.cnblogs.com/cputn/p/8319201.html
Copyright © 2011-2022 走看看