zoukankan      html  css  js  c++  java
  • python实现计算器

      1 import re
      2 import functools
      3  
      4  
      5 def minus_operator_handler(formula):
      6     '''处理一些特殊的减号运算'''
      7     minus_operators = re.split("-",formula)
      8     calc_list= re.findall("[0-9]",formula)
      9     if minus_operators[0] == '': #第一值肯定是负号
     10         calc_list[0] = '-%s' % calc_list[0]
     11     res = functools.reduce(lambda x,y:float(x) - float(y), calc_list)
     12     print("33[33;1m减号[%s]处理结果:33[0m" % formula, res )
     13     return res
     14  
     15 def remove_duplicates(formula):
     16     formula = formula.replace("++","+")
     17     formula = formula.replace("+-","-")
     18     formula = formula.replace("-+","-")
     19     formula = formula.replace("--","+")
     20     formula = formula.replace("- -","+")
     21     return formula
     22 def compute_mutiply_and_dividend(formula):
     23     '''算乘除,传进来的是字符串噢'''
     24     operators = re.findall("[*/]", formula )
     25     calc_list = re.split("[*/]", formula )
     26     res = None
     27     for index,i in enumerate(calc_list):
     28         if res:
     29             if operators[index-1] == "*":
     30                 res *= float(i)
     31             elif operators[index-1] == "/":
     32                 res /= float(i)
     33         else:
     34             res = float(i)
     35  
     36     print("33[31;1m[%s]运算结果=33[0m" %formula, res  )
     37     return res
     38 def handle_minus_in_list(operator_list,calc_list):
     39     '''有的时候把算术符和值分开后,会出现这种情况  ['-', '-', '-'] [' ', '14969037.996825399 ', ' ', '12.0/ 10.0 ']
     40        这需要把第2个列表中的空格都变成负号并与其后面的值拼起来,恶心死了
     41     '''
     42     for index,i in enumerate(calc_list):
     43         if i == '': #它其实是代表负号,改成负号
     44             calc_list[index+1] = i + calc_list[index+1].strip()
     45 def handle_special_occactions(plus_and_minus_operators,multiply_and_dividend):
     46     '''有时会出现这种情况 , ['-', '-'] ['1 ', ' 2 * ', '14969036.7968254'],2*...后面这段实际是 2*-14969036.7968254,需要特别处理下,太恶心了'''
     47     for index,i in enumerate(multiply_and_dividend):
     48         i = i.strip()
     49         if i.endswith("*") or i.endswith("/"):
     50             multiply_and_dividend[index] = multiply_and_dividend[index] + plus_and_minus_operators[index] + multiply_and_dividend[index+1]
     51             del multiply_and_dividend[index+1]
     52             del plus_and_minus_operators[index]
     53     return plus_and_minus_operators,multiply_and_dividend
     54 def compute(formula):
     55     '''这里计算是的不带括号的公式'''
     56  
     57     formula = formula.strip("()") #去除外面包的拓号
     58     formula = remove_duplicates(formula) #去除外重复的+-号
     59     plus_and_minus_operators = re.findall("[+-]", formula)
     60     multiply_and_dividend = re.split("[+-]", formula) #取出乘除公式
     61     if len(multiply_and_dividend[0].strip()) == 0:#代表这肯定是个减号
     62         multiply_and_dividend[1] = plus_and_minus_operators[0] + multiply_and_dividend[1]
     63         del multiply_and_dividend[0]
     64         del plus_and_minus_operators[0]
     65  
     66     plus_and_minus_operators,multiply_and_dividend=handle_special_occactions(plus_and_minus_operators,multiply_and_dividend)
     67     for index,i in enumerate(multiply_and_dividend):
     68         if re.search("[*/]" ,i):
     69             sub_res = compute_mutiply_and_dividend(i)
     70             multiply_and_dividend[index] = sub_res
     71  
     72     #开始运算+,-
     73     print(multiply_and_dividend, plus_and_minus_operators)
     74     total_res = None
     75     for index,item in enumerate(multiply_and_dividend):
     76         if total_res: #代表不是第一次循环
     77             if plus_and_minus_operators[index-1] == '+':
     78                 total_res += float(item)
     79             elif plus_and_minus_operators[index-1] == '-':
     80                 total_res -= float(item)
     81         else:
     82             total_res = float(item)
     83     print("33[32;1m[%s]运算结果:33[0m" %formula,total_res)
     84     return total_res
     85  
     86 def calc(formula):
     87     '''计算程序主入口, 主要逻辑是先计算拓号里的值,算出来后再算乘除,再算加减'''
     88     parenthesise_flag = True
     89     calc_res = None #初始化运算结果为None,还没开始运算呢,当然为None啦
     90     while parenthesise_flag:
     91         m = re.search("([^()]*)", formula) #找到最里层的拓号
     92         if m:
     93             #print("先算拓号里的值:",m.group())
     94             sub_res = compute(m.group())
     95             formula = formula.replace(m.group(),str(sub_res))
     96         else:
     97             print('33[41;1m----没拓号了...---33[0m')
     98  
     99             print('
    
    33[42;1m最终结果:33[0m',compute(formula))
    100             parenthesise_flag = False #代表公式里的拓号已经都被剥除啦
    101  
    102 if __name__ == '__main__':
    103  
    104     #res = calc("1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )")
    105     res = calc("1 - 2 * ( (60-30 +(-9-2-5-2*3-5/3-40*4/2-3/5+6*3) * (-9-2-5-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )")
    为什么要坚持,想一想当初!
  • 相关阅读:
    ansible-playbook最佳实践
    zabbix 优化之 表分区
    ansible-playbook 打通ssh无秘钥
    jQuery 1.9 移除了 $.browser 的替代方法
    也谈前端基础设施建设
    滚动视差网站欣赏
    css常见的快捷开发代码汇总(长期更新)
    如何让搜索引擎抓取AJAX内容?
    Bookmarklet编写指南
    20个网页设计师应该学习的CSS3经典教程实例
  • 原文地址:https://www.cnblogs.com/JerryZao/p/8681379.html
Copyright © 2011-2022 走看看