• 教学项目之-通过Python实现简单的计算器


    教学项目之-通过Python实现简单的计算器

     

    计算器开发需求

    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
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    import re
    import functools
     
     
    def minus_operator_handler(formula):
        '''处理一些特殊的减号运算'''
        minus_operators = re.split("-",formula)
        calc_list= re.findall("[0-9]",formula)
        if minus_operators[0== '': #第一值肯定是负号
            calc_list[0= '-%s' % calc_list[0]
        res = functools.reduce(lambda x,y:float(x) - float(y), calc_list)
        print("33[33;1m减号[%s]处理结果:33[0m" % formula, res )
        return res
     
    def remove_duplicates(formula):
        formula = formula.replace("++","+")
        formula = formula.replace("+-","-")
        formula = formula.replace("-+","-")
        formula = formula.replace("--","+")
        formula = formula.replace("- -","+")
        return formula
    def compute_mutiply_and_dividend(formula):
        '''算乘除,传进来的是字符串噢'''
        operators = re.findall("[*/]", formula )
        calc_list = re.split("[*/]", formula )
        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)
     
        print("33[31;1m[%s]运算结果=33[0m" %formula, res  )
        return res
    def handle_minus_in_list(operator_list,calc_list):
        '''有的时候把算术符和值分开后,会出现这种情况  ['-', '-', '-'] [' ', '14969037.996825399 ', ' ', '12.0/ 10.0 ']
           这需要把第2个列表中的空格都变成负号并与其后面的值拼起来,恶心死了
        '''
        for index,i in enumerate(calc_list):
            if == '': #它其实是代表负号,改成负号
                calc_list[index+1= + calc_list[index+1].strip()
    def handle_special_occactions(plus_and_minus_operators,multiply_and_dividend):
        '''有时会出现这种情况 , ['-', '-'] ['1 ', ' 2 * ', '14969036.7968254'],2*...后面这段实际是 2*-14969036.7968254,需要特别处理下,太恶心了'''
        for index,i in enumerate(multiply_and_dividend):
            = 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 compute(formula):
        '''这里计算是的不带括号的公式'''
     
        formula = formula.strip("()"#去除外面包的拓号
        formula = remove_duplicates(formula) #去除外重复的+-号
        plus_and_minus_operators = re.findall("[+-]", formula)
        multiply_and_dividend = re.split("[+-]", formula) #取出乘除公式
        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=handle_special_occactions(plus_and_minus_operators,multiply_and_dividend)
        for index,i in enumerate(multiply_and_dividend):
            if re.search("[*/]" ,i):
                sub_res = compute_mutiply_and_dividend(i)
                multiply_and_dividend[index] = sub_res
     
        #开始运算+,-
        print(multiply_and_dividend, plus_and_minus_operators)
        total_res = None
        for index,item in enumerate(multiply_and_dividend):
            if total_res: #代表不是第一次循环
                if plus_and_minus_operators[index-1== '+':
                    total_res += float(item)
                elif plus_and_minus_operators[index-1== '-':
                    total_res -= float(item)
            else:
                total_res = float(item)
        print("33[32;1m[%s]运算结果:33[0m" %formula,total_res)
        return total_res
     
    def calc(formula):
        '''计算程序主入口, 主要逻辑是先计算拓号里的值,算出来后再算乘除,再算加减'''
        parenthesise_flag = True
        calc_res = None #初始化运算结果为None,还没开始运算呢,当然为None啦
        while parenthesise_flag:
            = re.search("([^()]*)", formula) #找到最里层的拓号
            if m:
                #print("先算拓号里的值:",m.group())
                sub_res = compute(m.group())
                formula = formula.replace(m.group(),str(sub_res))
            else:
                print('33[41;1m----没拓号了...---33[0m')
     
                print(' 33[42;1m最终结果:33[0m',compute(formula))
                parenthesise_flag = False #代表公式里的拓号已经都被剥除啦
     
    if __name__ == '__main__':
     
        #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) )")
        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) )")

      

     
     
    好文要顶 关注我 收藏该文  
    0
    0
     
     
     
    « 上一篇:Python Select 解析
    posted @ 2016-01-29 19:17 金角大王 阅读(1035) 评论(0)  编辑 收藏

     
     
  • 相关阅读:
    Ajax返回DataSet时
    spring(8)
    spring(12)
    spring(6)
    spring(11)
    spring(10)
    spring(5)
    spring(3)
    spring(9)
    spring(7)
  • 原文地址:https://www.cnblogs.com/weiman3389/p/6222649.html
Copyright © 2020-2023  润新知