zoukankan      html  css  js  c++  java
  • 简单计算器

    计算器开发需求

    1. 实现加减乘除及拓号优先级解析
    2. 用户输入 1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )等类似公式后,必须自己解析里面的(),+,-,*,/符号和公式,运算后得出结果,结果必须与真实的计算器所得出的结果一致
        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("减号[%s]处理结果:" % formula, res)
       13     return res
       14 
       15 
       16 def remove_duplicates(formula):
       17     formula = formula.replace("++", "+")
       18     formula = formula.replace("+-", "-")
       19     formula = formula.replace("-+", "-")
       20     formula = formula.replace("--", "+")
       21     formula = formula.replace("- -", "+")
       22     return formula
       23 
       24 
       25 def compute_mutiply_and_dividend(formula):
       26     '''算乘除,传进来的是字符串噢'''
       27     operators = re.findall("[*/]", formula)
       28     calc_list = re.split("[*/]", formula)
       29     res = None
       30     for index, i in enumerate(calc_list):
       31         if res:
       32             if operators[index - 1] == "*":
       33                 res *= float(i)
       34             elif operators[index - 1] == "/":
       35                 res /= float(i)
       36         else:
       37             res = float(i)
       38 
       39     print("[%s]运算结果=" % formula, res)
       40     return res
       41 
       42 
       43 def handle_minus_in_list(operator_list, calc_list):
       44     '''有的时候把算术符和值分开后,会出现这种情况  ['-', '-', '-'] [' ', '14969037.996825399 ', ' ', '12.0/ 10.0 ']
       45        这需要把第2个列表中的空格都变成负号并与其后面的值拼起来,恶心死了
       46     '''
       47     for index, i in enumerate(calc_list):
       48         if i == '':  # 它其实是代表负号,改成负号
       49             calc_list[index + 1] = i + calc_list[index + 1].strip()
       50 
       51 
       52 def handle_special_occactions(plus_and_minus_operators, multiply_and_dividend):
       53     '''有时会出现这种情况 , ['-', '-'] ['1 ', ' 2 * ', '14969036.7968254'],2*...后面这段实际是 2*-14969036.7968254,需要特别处理下,太恶心了'''
       54     for index, i in enumerate(multiply_and_dividend):
       55         i = i.strip()
       56         if i.endswith("*") or i.endswith("/"):
       57             multiply_and_dividend[index] = multiply_and_dividend[index] + plus_and_minus_operators[index] + 
       58                                            multiply_and_dividend[index + 1]
       59             del multiply_and_dividend[index + 1]
       60             del plus_and_minus_operators[index]
       61     return plus_and_minus_operators, multiply_and_dividend
       62 
       63 
       64 def compute(formula):
       65     '''这里计算是的不带括号的公式'''
       66 
       67     formula = formula.strip("()")  # 去除外面包的拓号
       68     formula = remove_duplicates(formula)  # 去除外重复的+-号
       69     plus_and_minus_operators = re.findall("[+-]", formula)
       70     multiply_and_dividend = re.split("[+-]", formula)  # 取出乘除公式
       71     if len(multiply_and_dividend[0].strip()) == 0:  # 代表这肯定是个减号
       72         multiply_and_dividend[1] = plus_and_minus_operators[0] + multiply_and_dividend[1]
       73         del multiply_and_dividend[0]
       74         del plus_and_minus_operators[0]
       75 
       76     plus_and_minus_operators, multiply_and_dividend = handle_special_occactions(plus_and_minus_operators,
       77                                                                                 multiply_and_dividend)
       78     for index, i in enumerate(multiply_and_dividend):
       79         if re.search("[*/]", i):
       80             sub_res = compute_mutiply_and_dividend(i)
       81             multiply_and_dividend[index] = sub_res
       82 
       83     # 开始运算+,-
       84     print(multiply_and_dividend, plus_and_minus_operators)
       85     total_res = None
       86     for index, item in enumerate(multiply_and_dividend):
       87         if total_res:  # 代表不是第一次循环
       88             if plus_and_minus_operators[index - 1] == '+':
       89                 total_res += float(item)
       90             elif plus_and_minus_operators[index - 1] == '-':
       91                 total_res -= float(item)
       92         else:
       93             total_res = float(item)
       94     print("[%s]运算结果:" % formula, total_res)
       95     return total_res
       96 
       97 
       98 def calc(formula):
       99     '''计算程序主入口, 主要逻辑是先计算拓号里的值,算出来后再算乘除,再算加减'''
      100     parenthesise_flag = True
      101     calc_res = None  # 初始化运算结果为None,还没开始运算呢,当然为None啦
      102     while parenthesise_flag:
      103         m = re.search("([^()]*)", formula)  # 找到最里层的拓号
      104         if m:
      105             # print("先算拓号里的值:",m.group())
      106             sub_res = compute(m.group())
      107             formula = formula.replace(m.group(), str(sub_res))
      108         else:
      109             print('……没括号了……')
      110 
      111             print('
      最终结果:', compute(formula))
      112             parenthesise_flag = False  # 代表公式里的拓号已经都被剥除啦
      113 
      114 
      115 if __name__ == '__main__':
      116     # 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) )")
      117     res = calc(
      118         "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) )")
      简单计算器
      import re
      from functools import reduce
      from tkinter import *
      '''处理特殊-号运算'''
      
      
      def minus_operation(expresstion):
          minus_operators = re.split("-", expresstion)
          calc_list = re.findall("[0-9]", expresstion)
          if minus_operators[0] == "":
              calc_list[0] = '-%s' % calc_list[0]
          res = reduce(lambda x, y: float(x) - float(y), calc_list)
          print(">>>>>>>>>>>>>>减号[%s]运算结果:" % expresstion, res)
          return res
      
      '''reduce()对sequence连续使用function, 如果不给出initial, 则第一次调用传递sequence的两个元素,
      以后把前一次调用的结果和sequence的下一个元素传递给function'''
      
      '''处理双运算符号'''
      
      
      def del_duplicates(expresstion):
      
          expresstion = expresstion.replace("++", "+")
          expresstion = expresstion.replace("--", "-")
          expresstion = expresstion.replace("+-", "-")
          expresstion = expresstion.replace("--", "+")
          expresstion = expresstion.replace('- -', "+")
          return expresstion
      
      '''*/运算函数'''
      
      
      def mutiply_dividend(expresstion):
          calc_list = re.split("[*/]", expresstion)  # 用* or /分割公式
          operators = re.findall("[*/]", expresstion)  # 找出所有*和/号
          res = None
          for index, i in enumerate(calc_list):
              if res:
                  if operators[index - 1] == '*':
                      res *= float(i)
                  elif operators[index - 1] == '/':
                      res /= float(i)
              else:
                  res = float(i)
          procession0 = "[%s]运算结果=" % expresstion, res
          # final_result.insert(END, procession0)  # 插入窗体
          print(procession0)
          return res
      
      '''处理运算符号顺序混乱情况'''
      
      
      def special_features(plus_and_minus_operators, multiply_and_dividend):
      
      
          for index, i in enumerate(multiply_and_dividend):
              i = i.strip()
              if i.endswith("*") or i.endswith("/"):
                  multiply_and_dividend[index] = multiply_and_dividend[index] + plus_and_minus_operators[index] + multiply_and_dividend[index + 1]
                  del multiply_and_dividend[index + 1]
                  del plus_and_minus_operators[index]
              return plus_and_minus_operators, multiply_and_dividend
      
      
      def minus_special(operator_list, calc_list):
          for index, i in enumerate(calc_list):
              if i == '':
                  calc_list[index + 1] = i + calc_list[index + 1].strip()
      
      
      '''运算除了()的公式+-*/'''
      
      
      def figure_up(expresstion):
          expresstion = expresstion.strip("()")  # 去掉外面括号
          expresstion = del_duplicates(expresstion)  # 去掉重复+-号
          plus_and_minus_operators = re.findall("[+-]", expresstion)
          multiply_and_dividend = re.split("[+-]", expresstion)
          if len(multiply_and_dividend[0].strip()) == 0:
              multiply_and_dividend[1] = plus_and_minus_operators[0] + multiply_and_dividend[1]
              del multiply_and_dividend[0]
              del plus_and_minus_operators[0]
      
          plus_and_minus_operators, multiply_and_dividend = special_features(plus_and_minus_operators, multiply_and_dividend)
          for index, i in enumerate(multiply_and_dividend):
              if re.search("[*/]", i):
                  sub_res = mutiply_dividend(i)
                  multiply_and_dividend[index] = sub_res
      
          # print(multiply_and_dividend, plus_and_minus_operators)  # 计算
          final_res = None
          for index, item in enumerate(multiply_and_dividend):
              if final_res:
                  if plus_and_minus_operators[index - 1] == '+':
                      final_res += float(item)
                  elif plus_and_minus_operators[index - 1] == '-':
                      final_res -= float(item)
              else:
                  final_res = float(item)
                  procession = '[%s]计算结果:' % expresstion, final_res
              # final_result.insert(END, procession)  # 插入窗体
              # print(procession)
          return final_res
      
      """主函数:运算逻辑:先计算拓号里的值,算出来后再算乘除,再算加减"""
      
      
      def calculate():
          expresstion = expresstions.get()  # 获取输入框值
          flage = True
          calculate_res = None  # 初始化计算结果为None
          while flage:
              m = re.search("([^()]*)", expresstion)  # 先找最里层的()
          # pattern = re.compile(r"([^()]*)")
          # m = pattern.match(expresstion)
              if m:
                  sub_res = figure_up(m.group())  # 运算()里的公式
                  expresstion = expresstion.replace(m.group(), str(sub_res))  # 运算完毕把结果替换掉公式
              else:
                  # print('---------------括号已经计算完毕--------------')
                  procession1 = "最终计算结果:%s
      "%figure_up(expresstion)
                  print(procession1)
                  final_result.insert(END, procession1)  # 插入窗体
                  # print('33[31m最终计算结果:', figure_up(expresstion))
                  flage = False
      
      if __name__ == "__main__":
      # res = calculate("1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )")
          window = Tk()  ###创建窗体
          window.title('计算器')  ###命名窗体
          frame1 = Frame(window)  ###框架1
          frame1.pack()  ###放置
          frame2 = Frame(window)  ###框架2
          frame2.pack()  ###放置
          lable = Label(frame1, text="请输入公式:")  ###文字标签
          lable.pack()
          expresstions = StringVar()  ###输入框属性,字符串
          entryname = Entry(frame1, textvariable=expresstions)  ###文本输入框
          bt_get_expresstions = Button(frame1, text="提交", command=calculate)  ###按钮挂件
          bt_get_expresstions.pack()
          entryname.pack()
          lable.grid_slaves(row=1,column=1)
          entryname.grid_slaves(row=1,column=1)
          bt_get_expresstions.grid_slaves(row=1,column=3)
          final_result = Text(frame2)  ###计算结果显示框
          final_result.tag_config("here", background="yellow", foreground="blue")
          final_result.pack()
          window.mainloop()  ###事件循环
      窗口计算器
      import re
      def math(dic):
          x, y = float(dic['x']), float(dic['y'])
          if dic['mark'] == '+': return x + y
          elif dic['mark'] == '-': return x - y
          elif dic['mark'] == '*': return x * y
          else: return x / y
      def suansu(re_str):
          ret4 = re.search(r'(?P<x>d+.?d*)(?P<mark>[*/])(?P<y>[-]?d+.?d*)', re_str)
          try:
              while ret4.group():
                  re_str = re_str.replace(ret4.group(), str(math(ret4.groupdict())))
                  if '--' in re_str: re_str = re_str.replace('--', '+')
                  if '++' in re_str: re_str = re_str.replace('++', '+')
                  ret4 = re.search(r'(?P<x>[-]?d+.?d*)(?P<mark>[*/])(?P<y>[-]?d+.?d*)', re_str)
          except AttributeError: pass
          ret4 = re.search(r'(?P<x>[-]?d+.?d*)(?P<mark>[+-])(?P<y>[-]?d+.?d*)', re_str)
          try:
              while ret4.group():
                  re_str = re_str.replace(ret4.group(), str(math(ret4.groupdict())))
                  ret4 = re.search(r'(?P<x>[-]?d+.?d*)(?P<mark>[+-])(?P<y>[-]?d+.?d*)', re_str)
          except AttributeError: return re_str
      def main(user_inp):
          while True:
              if not re.search('([+*/d.-]*)', user_inp):
                  print(user_inp)
                  return suansu(user_inp)
              else:
                  for i in re.findall('([+*/d.-]*)', user_inp):
                      user_inp = user_inp.replace(i, suansu(i.replace('(', '').replace(')', '')))
      while True: print(main('0+'+input('>>>').replace(" ", "")))
      精简版计算器
  • 相关阅读:
    滑动加载
    关于git的常用命令
    github相关指令学习
    jquery的contains方法
    vertical-align_CSS参考手册_web前端开发参考手册系列
    关于拜读张鑫旭文章,了解的新属性
    如何从GitHub仓库clone项目
    关于小窗滑动,父级body也跟随滑动的解决方案(2)
    vue父子组件传递参数之props
    JsExcelXml.js的源码
  • 原文地址:https://www.cnblogs.com/yifugui/p/7384200.html
Copyright © 2011-2022 走看看