计算器简单篇(项目篇)

一、功能分析

日常生活中我们用的计算器都包括加减乘除幂平方立方1 - 2 * ( (60-30 +(-9**5-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) )这么这么长的一个式子,大家算的时候都知道先算幂,立方,平方,再算乘除,加减

二、知识点

所用到的python的知识点有:

  • 正则表达式re模块

  • 字符串的处理

三、程序实现流程分析

  • 用正则表达式处理字符串,只提取其中的数字和运算符,并转换成列表

  • 编写一个函数,处理没有括号的基本运算的基本表达式

  • 再写一个函数递归处理带有括号的函数,先计算最内部括号中的表达式, 然后将最内部的括号替换为计算后的结果, 在递归外部一层的, 最后返回的就是所需的结果

四、代码部分

上面也说了处理的时候先处理幂,平方,立方

1、处理幂函数

import re,sys
def Power(arg):
    '''
    计算幂函数
    :param arg: 传进来的等式
    :return: 返回计算完的等式
    '''
    while True:
        relust = re.split(r"(d+.?d*[*/]{2}-?d+.?d*)", arg, 1)
        if len(relust) == 3:                                    # 判断切割出来的是不是3个元素
            before = relust[0]                                  # 第一个元素赋值给before
            content = relust[1]                                   # 第二个元素赋值给content
            after = relust[2]
            if "**" in content:                                 #如果等式里面有“**”
                start,end = content.split("**")                 #用**吧分割开
                finlly = float(start) ** float(end)              #计算幂等式
                arg = before + str(finlly) + after               #把结果替换回原等式
        else:
            return arg

2、处理乘除

从左往右的时候不能先算乘,必须遇到乘就算乘遇到除就算除,楼主在这踩过坑,所以大家也注意下:

def Multply_didvid(arg):         #定义乘除运算的函数
    '''
    计算加减
    :param arg: 传进来的算法
    :return: 返回运算结果
    '''
    while True:                                                                 #while循环每一次传进来的运算
        arg = re.sub(r"++","+",arg)
        arg = re.sub(r"+-", "-", arg)
        arg = re.sub(r"-+", "-", arg)
        arg = re.sub(r"--", "+", arg)
        relust = re.split(r"(d+.?d*[*/]-?d+.?d*)",arg,1)              #把从左往右第一次匹配到得乘法
        # print(relust)
        if len(relust) ==3:                                                     #判断切割出来的是不是3个元素
            before = relust[0]                                                  #第一个元素赋值给before
            content = relust[1]                                                 #第二个元素赋值给content
            after = relust[2]                                                   #第三个元素赋值给after

            if "*" in content:                                                 #判断第二个元素里面有没有"*"
                start,end = content.split("*")                                 #用“*”把分割开赋值给start,end
                finlly = float(start) * float(end)                             #运算出乘法
                arg = before+str(finlly)+after                                #替换原来的运算式

            else:                                                              #否则就是除法
                start, end = content.split("/")                                #用/分割开赋值给start,end
                finlly = float(start) / float(end)                             #把除法算出来
                arg = before + str(finlly) + after                             #替换原来的元算是
                # print(arg)
        else:
            return arg                                                         #将运算结果返回去

3、处理加减

加减是最简单的,把每个数字带前面的符号给切割出来,然后给定义一个计数器,依次相加就可得出结果

def Add_sub(arg):                                                             #加减法运算-9-2-5-2+5-3
    '''
    计算加减运算
    :param arg: 传进来的算术
    :return: 返回运算结果
    '''
    result = re.findall(r"[+-]?d+.?d*",arg)                            #列出所有的元素
    start = 0                                                                  #定义空值让他挨个去加
    for i in result:
        start += float(i)                                                    #让素有元素相加
    return start                                                             #返回运算结果

4、式子处理函数

拿到式子,我们肯定是先处理式子,把有括号得拿出来处理

def Calculate(source):
    '''
    计算函数
    :param source: 传进来的等式
    :return: 返回计算结果
    '''
    while True:
        source = re.sub(r"s*", "", source)                                        #去掉空格
        source = source.replace("++","+").replace("+-","-").replace("--","+").replace("-+","-")     #替换符号
        res = re.split(r"(([^()]+))",source,1)                                   #先取出括号里面的值
        if len(res) ==3:                                                            #判断分割出来的是不是3个元素
            before = res[0]                                                          #分别将元素赋值给三个值
            content = res[1]
            after = res[2]
            powe = Power(content)
            mu_di = Multply_didvid(powe)                                        #执行乘除
            ad_su = Add_sub(mu_di)                                                 #执行加减
            res = before + str(ad_su) + after                                      #运算结果替换原来等式
            source = res                                                            #赋值给其他传进来元素
            #print("去括号得到得值为:",source)
        else:
            powe = Power(source)
            mu_di = Multply_didvid(powe)                                         #没括号得等式
            ad_su = Add_sub(mu_di)                                                 #计算加法
            source = ad_su
            # print('最后结果为:',ad_su)                                            #打印最后结果
            return source

到这里为止,代码就可以算是完成了,下面把代码总和起来,可以运行试试看:

import re,sys
def Power(arg):
    '''
    计算幂函数
    :param arg: 传进来的等式
    :return: 返回计算完的等式
    '''
    while True:
        relust = re.split(r"(d+.?d*[*/]{2}-?d+.?d*)", arg, 1)
        if len(relust) == 3:                                    # 判断切割出来的是不是3个元素
            before = relust[0]                                  # 第一个元素赋值给before
            content = relust[1]                                   # 第二个元素赋值给content
            after = relust[2]
            if "**" in content:                                 #如果等式里面有“**”
                start,end = content.split("**")                 #用**吧分割开
                finlly = float(start) ** float(end)              #计算幂等式
                arg = before + str(finlly) + after               #把结果替换回原等式
        else:
            return arg


def Multply_didvid(arg):         #定义乘除运算的函数
    '''
    计算加减
    :param arg: 传进来的算法
    :return: 返回运算结果
    '''
    while True:                                                                 #while循环每一次传进来的运算
        arg = re.sub(r"++","+",arg)
        arg = re.sub(r"+-", "-", arg)
        arg = re.sub(r"-+", "-", arg)
        arg = re.sub(r"--", "+", arg)
        relust = re.split(r"(d+.?d*[*/]-?d+.?d*)",arg,1)              #把从左往右第一次匹配到得乘法
        # print(relust)
        if len(relust) ==3:                                                     #判断切割出来的是不是3个元素
            before = relust[0]                                                  #第一个元素赋值给before
            content = relust[1]                                                 #第二个元素赋值给content
            after = relust[2]                                                   #第三个元素赋值给after

            if "*" in content:                                                 #判断第二个元素里面有没有"*"
                start,end = content.split("*")                                 #用“*”把分割开赋值给start,end
                finlly = float(start) * float(end)                             #运算出乘法
                arg = before+str(finlly)+after                                #替换原来的运算式

            else:                                                              #否则就是除法
                start, end = content.split("/")                                #用/分割开赋值给start,end
                finlly = float(start) / float(end)                             #把除法算出来
                arg = before + str(finlly) + after                             #替换原来的元算是
                # print(arg)
        else:
            return arg                                                         #将运算结果返回去


def Add_sub(arg):                                                             #加减法运算-9-2-5-2+5-3
    '''
    计算加减运算
    :param arg: 传进来的算术
    :return: 返回运算结果
    '''
    result = re.findall(r"[+-]?d+.?d*",arg)                            #列出所有的元素
    start = 0                                                                  #定义空值让他挨个去加
    for i in result:
        start += float(i)                                                    #让素有元素相加
    return start                                                             #返回运算结果



def Calculate(source):
    '''
    计算函数
    :param source: 传进来的等式
    :return: 返回计算结果
    '''
    while True:
        source = re.sub(r"s*", "", source)                                        #去掉空格
        source = source.replace("++","+").replace("+-","-").replace("--","+").replace("-+","-")     #替换符号
        res = re.split(r"(([^()]+))",source,1)                                   #先取出括号里面的值
        if len(res) ==3:                                                            #判断分割出来的是不是3个元素
            before = res[0]                                                          #分别将元素赋值给三个值
            content = res[1]
            after = res[2]
            powe = Power(content)
            mu_di = Multply_didvid(powe)                                        #执行乘除
            ad_su = Add_sub(mu_di)                                                 #执行加减
            res = before + str(ad_su) + after                                      #运算结果替换原来等式
            source = res                                                            #赋值给其他传进来元素
            #print("去括号得到得值为:",source)
        else:
            powe = Power(source)
            mu_di = Multply_didvid(powe)                                         #没括号得等式
            ad_su = Add_sub(mu_di)                                                 #计算加法
            source = ad_su
            # print('最后结果为:',ad_su)                                            #打印最后结果
            return source

print('
****************************************************************')
print('                33[33m 欢迎使用计算器(^-_-^) 33[0m')
print('
****************************************************************')
print("计算等式直接复制即可!:","1 - 2 *  ( (60-30 +(-9**5-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) )")
while True:
    inp = input("请输入计算等式(q退出):")
    if inp =="q":
        sys.exit("欢迎下次光临!")
    elif  not inp.strip():
        inp = inp.strip()
        continue
    else:
        fin = Calculate(inp)
        print("计算结果为:%s" % fin)
        print("eval结果为:%s" % eval(inp))
计算器

五:总结

死是不是发现还有点复杂,我相信大家还能写出更简单的,当然python为了追求简单,一行代码也可以搞定,eval()函数直接搞定,但是自己写下好提高自己的能力嘛,嘿嘿

原文地址:https://www.cnblogs.com/aylin/p/5517793.html