import re

# 计算器基本功能函数定义
# 幂运算:**
def power(f):
    '''
    幂运算,power
    :param f: 需要运算的公式,如:f = '2**3'
    :return: 幂运算的结果f,str
    '''
    # print(f,type(f)) #测试用
    ret = re.split('\*\*',f)
    if len(ret) == 2:
        f = str(float(ret[0])**float(ret[1]))
    return f

# 乘除运算:*|
def cheng_chu(f):
    '''
    乘法和除法是同级运算,本函数进行乘除法运算并返回结果。
    :param f: 待运算的公式,如2*3、3/4。
    :return:  运算结果f,str
    '''
    ret = re.split(r'([*/])', f)
    if len(ret) == 3:
        if ret[1] == '*':
            f = str(float(ret[0]) * float(ret[2]))
        else:
            f = str(float(ret[0]) / float(ret[2]))
    return f

# 加减运算:+-
def jia_jian(f):
    '''
    加法和减法是同级运算,本函数进行加减法运算并返回结果。
    :param f: 待运算的公式,如2+3、3-4。
    :return:  运算结果f,str
    '''
    ret = re.split('([+-])', f)
    if len(ret) == 3:
        if ret[1] == '+':
            f = str(float(ret[0]) + float(ret[2]))
        else:
            f = str(float(ret[0]) - float(ret[2]))
    return f

# 不含()的公式运算
# 使用自定义函数power()、cheng_chu()、jia_jian()
def no_bracket_formula(fa):
    '''
    完成不带括号的公式运算,如:'1+3-3*2'。
    :param fa: 待运算的公式,str
    :return: 返回运算结果,str
    '''
    # print(fa) # 测试用
    # 首先,进行幂运算
    while True:
        ret = re.split('(\d+\.?\d*\*\*\d+\.?\d*)',fa,1)
        # print(ret) # 测试用
        if len(ret) == 3:
            ret[1] = power(ret[1])
            fa = ret[0] + ret[1] + ret[2]
            # print(fa)  # 测试用
            continue
        else:
            break
    # print(fa,type(fa)) # 测试用
    # 其次,进行乘法和除法运算
    while True:
        ret = re.split('(\d+\.?\d*[*/]\d+\.?\d*)',fa,1)
        # print(ret) # 测试用
        if len(ret) == 3:
            ret[1] = cheng_chu(ret[1])
            fa = ret[0] + ret[1] + ret[2]
            # print(fa)  # 测试用
            continue
        else:
            break
    # print(fa, type(fa))  # 测试用
    # 最后,进行加减运算
    while True:
        if fa == re.match('[-+]?\d+\.?\d*', fa): # 只剩下一个数值时,结束
            break
        else:            #不止一个数值时,继续运算
            ret = re.split('(\d+\.?\d*)',fa,2)  # 找到需要运算的两个数值,切割
            # print('ret=',ret)  # 测试用
            if len(ret) == 5:
                if (ret[0] == ret[2]) or (ret[0] == '' and ret[2] == '+') :
                    fa = str(ret[0] + jia_jian(ret[1] + '+' + ret[3]) + ret[4])
                else:
                    fa = str(ret[0] + jia_jian(ret[1] + '-' + ret[3]) + ret[4])
                # print(fa)  # 测试用
                continue
            else:
                break
    # print(fa, type(fa))  # 测试用
    #返回运算结果
    return fa

def main(fa):
    '''
    完成数学公式的运算。
    思路:使用re.split()先计算()内部运算式;在求总体结果。
    :param fa: 需要进行运算的公式
    :return: 公式计算结果
    '''
    while True:
        # 找出进行运算的()内公式
        ret = re.split('\(([^()]+)\)',fa,1)
        # 运算()公式,结果替换原公式中()部分
        if len(ret) == 3:
            ret[1] = str(no_bracket_formula(ret[1]))
            fa = ret[0] + ret[1] + ret[2]
            continue
        else:
            break
    return no_bracket_formula(fa)

# 函数调用,进行公式运算,并返回结果
fa = '10**3+(20-(3*5)**(2.4/4.2))/5.5+5-(4*2-3)'
ret = main(fa)
print(fa,'=',ret)
print(eval(fa)) # 测试用