简单计算器

计算器开发需求

  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('\n最终结果:', 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\n"%figure_up(expresstion)
                print(procession1)
                final_result.insert(END, procession1)  # 插入窗体
                # print('\033[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(" ", "")))
    精简版计算器
posted @ 2017-08-17 20:22  Fugui  阅读(290)  评论(0编辑  收藏  举报