博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
python 计算器
阅读量:6482 次
发布时间:2019-06-23

本文共 5302 字,大约阅读时间需要 17 分钟。

hot3.png

#!/usr/bin/env python# -*- coding:utf-8 -*-"""该计算器思路:    1、递归寻找表达式中只含有 数字和运算符的表达式,并计算结果    2、由于整数计算会忽略小数,所有的数字都认为是浮点型操作,以此来保留小数使用技术:    1、正则表达式    2、递归(python中递归返回值是None,这点是坑) 执行流程如下:******************** 请计算表达式: 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: ['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=-8.0after: ['1-2*((60-30+-8.0*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))']========== 上一次计算结束 ==========before: ['1-2*((60-30+-8.0*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))']9-2*5/3+7/3*99/4*2998+10*568/14=173545.880953after: ['1-2*((60-30+-8.0*173545.880953)-(-4*3)/(16-3*2))']========== 上一次计算结束 ==========before: ['1-2*((60-30+-8.0*173545.880953)-(-4*3)/(16-3*2))']60-30+-8.0*173545.880953=-1388337.04762after: ['1-2*(-1388337.04762-(-4*3)/(16-3*2))']========== 上一次计算结束 ==========before: ['1-2*(-1388337.04762-(-4*3)/(16-3*2))']-4*3=-12.0after: ['1-2*(-1388337.04762--12.0/(16-3*2))']========== 上一次计算结束 ==========before: ['1-2*(-1388337.04762--12.0/(16-3*2))']16-3*2=10.0after: ['1-2*(-1388337.04762--12.0/10.0)']========== 上一次计算结束 ==========before: ['1-2*(-1388337.04762--12.0/10.0)']-1388337.04762--12.0/10.0=-1388335.84762after: ['1-2*-1388335.84762']========== 上一次计算结束 ==========我的计算结果: 2776672.69524"""  import re  def compute_mul_div(arg):    """ 操作乘除    :param expression:表达式    :return:计算结果    """     val = arg[0]    mch = re.search('\d+\.*\d*[\*\/]+[\+\-]?\d+\.*\d*', val)    if not mch:        return    content = re.search('\d+\.*\d*[\*\/]+[\+\-]?\d+\.*\d*', 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 = re.split('\d+\.*\d*[\*\/]+[\+\-]?\d+\.*\d*', 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:计算结果    """     arg[0] = arg[0].replace('+-','-')    arg[0] = arg[0].replace('++','+')    arg[0] = arg[0].replace('-+','-')    arg[0] = arg[0].replace('--','+')     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]    mch = re.search('\d+\.*\d*[\+\-]{1}\d+\.*\d*', val)    if not mch:        return    content = re.search('\d+\.*\d*[\+\-]{1}\d+\.*\d*', 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 = re.split('\d+\.*\d*[\+\-]{1}\d+\.*\d*', 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_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(inp_list):    """ 递归处理括号,并计算    :param expression: 表达式    :return:最终计算结果    """    # 如果表达式中已经没有括号,则直接调用负责计算的函数,将表达式结果返回,如:2*1-82+444    if not re.search('\(([\+\-\*\/]*\d+\.*\d*){2,}\)', inp_list[0]):        final = compute(inp_list[0])        inp_list[0] = final        return inp_list    # 获取 第一个 只含有 数字/小数 和 操作符 的括号    # 如:    #    ['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 = re.search('\(([\+\-\*\/]*\d+\.*\d*){2,}\)', inp_list[0]).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 = re.split('\(([\+\-\*\/]*\d+\.*\d*){2,}\)', inp_list[0], 1)     print 'before:',inp_list    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))']    inp_list[0] = "%s%s%s" %(before, ret, after)    print 'after:',inp_list    print "="*10,'上一次计算结束',"="*10     # 循环继续下次括号处理操作,本次携带者的是已被处理后的表达式,即:    # ['1-2*((60-30+   -8.0  *(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))']     # 如此周而复始的操作,直到表达式中不再含有括号    exec_bracket(inp_list)   # 使用 __name__ 的目的:#   只有执行 python index.py 时,以下代码才执行#   如果其他人导入该模块,以下代码不执行if __name__ == "__main__":    print '*'*20,"请计算表达式:", "1 - 2 * ( (60-30 +(-40.0/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )" ,'*'*20    inpp = '1 - 2 * ( (60-30 +(-40.0/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) ) '    inpp = re.sub('\s*','',inpp)    # 由于python的递归的坑,所有要把表达式保存在列表中    inp_list = [inpp,]    exec_bracket(inp_list)    final = inp_list[0]    print "我的计算结果:",final    print "eval计算结果(正是计算器不可取):",eval('1 - 2 * ( (60-30 +(-40.0/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) ) ')

转载于:https://my.oschina.net/eddylinux/blog/528080

你可能感兴趣的文章
深入理解JavaScript系列(18):面向对象编程之ECMAScript实现
查看>>
如何改变Android tab 的高度和字体大小
查看>>
hdu 2853
查看>>
【转】java与C++的区别
查看>>
VS2013 MVC Web项目使用内置的IISExpress支持局域网内部机器(手机、PC)访问、调试...
查看>>
Error: java.lang.UnsatisfiedLinkError: no ntvinv in java.library.path
查看>>
Vue.js常用指令:v-show和v-if
查看>>
java自定义接口
查看>>
Codeforces Round #152 (Div. 2) B题 数论
查看>>
马云马化腾等大佬,是如何看待区块链的?
查看>>
10倍于行业增速!海尔冰箱套圈引领
查看>>
Java集合总结【面试题+脑图】,将知识点一网打尽!
查看>>
API开发中如何使用限速应对大规模访问
查看>>
java基础(十) 数组类型
查看>>
小程序 Canvas绘图不同尺寸设备 UI兼容的两个解决方案
查看>>
产品规划,你通常规划多久的时间线?
查看>>
Android-MVP架构
查看>>
HTML5前端教程分享:CSS浏览器常见兼容问题
查看>>
Material Design之AppBarLayout
查看>>
Linux系统VNC配置
查看>>