欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

python写计算器

程序员文章站 2022-04-02 11:17:02
...

python写计算器

l = '1-2*((60-30+(-40/5)*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))'
import re

def compute_mul_div(arg):  # 计算乘除,接收列表[expression, 0]
    val = arg[0]    # 获取表达式
    mch = re.search('\d+\.*\d*[\*\/]+[\+\-]?\d+\.*\d*', val)  # 匹配乘法或除法
    if not mch:  # 如果没有乘法或除法   # 递归结束条件
        return   # 结束函数
    content = re.search('\d+\.*\d*[\*\/]+[\+\-]?\d+\.*\d*', val).group()  # 寻找第一个乘法或除法

    if len(content.split('*')) > 1:   # 如是*
        n1, n2 = content.split('*')
        value = float(n1) * float(n2)  # 计算乘法
    else:                               # 如是/
        n1, n2 = content.split('/')
        value = float(n1) / float(n2)   # 计算除法

    before, after = re.split('\d+\.*\d*[\*\/]+[\+\-]?\d+\.*\d*', val, 1)  # 等式用第一个乘法或除法分割成一个列表
    new_str = "%s%s%s" % (before, value, after)  # 替换原等式
    arg[0] = new_str  # 更改列表第一个元素
    compute_mul_div(arg)  # 继续执行该函数,直到没有乘法或除法

def compute_add_sub(arg):  # 计算加减,参数为列表,第一个值为止含有加减法的等式,第二个值为0
    while True:
        if arg[0].__contains__('+-') or arg[0].__contains__("++") or arg[0].__contains__('-+') or arg[0].__contains__(
                "--"):      # 字符串中的 __contains__ 方法返回布尔值,判断参数是否在字符串中,如果等式含有以上4中之一,则替换
            arg[0] = arg[0].replace('+-', '-')
            arg[0] = arg[0].replace('++', '+')
            arg[0] = arg[0].replace('-+', '-')
            arg[0] = arg[0].replace('--', '+')
        else:    # 结束循环
            break

    if arg[0].startswith('-'):  # 如果等式以-好开头
        arg[1] += 1   # 列表中第二个值 + 1
        arg[0] = arg[0].replace('-', '&')
        arg[0] = arg[0].replace('+', '-')
        arg[0] = arg[0].replace('&', '+')
        arg[0] = arg[0][1:]
    val = arg[0]
    mch = re.search('\d+\.*\d*[\+\-]{1}\d+\.*\d*', val)  # 匹配加法或减法
    if not mch:  # 如没有 ,结束函数
        return
    content = re.search('\d+\.*\d*[\+\-]{1}\d+\.*\d*', val).group()  # 第一个加法或减法
    if len(content.split('+')) > 1:   # 如是加法
        n1, n2 = content.split('+')
        value = float(n1) + float(n2)
    else:     # 减法
        n1, n2 = content.split('-')
        value = float(n1) - float(n2)

    before, after = re.split('\d+\.*\d*[\+\-]{1}\d+\.*\d*', val, 1)  # 等式以第一个加法或减法分开
    new_str = "%s%s%s" % (before, value, after)  # 更新等式
    arg[0] = new_str  # 更新列表
    compute_add_sub(arg)  # 继续执行该函数,直到变成一个数字


def compute(expression):  # 先计算乘除,再计算加减
    inp = [expression, 0]  # 把无括号等式和0放入列表中
    compute_mul_div(inp)  # 把以上列表作为参数传给函数compute_mul_div,并执行该函数
    compute_add_sub(inp)
    if divmod(inp[1], 2)[1] == 1:
        result = float(inp[0])
        result = result * -1
    else:
        result = float(inp[0])
    return result


def exec_bracket(expression):  # 参数为没有空格的等式
    '''
    计算括号内的等式
    '''
    if not re.search('\(([\+\-\*\/]*\d+\.*\d*){2,}\)', expression):  # 匹配最内侧括号,如为空  # 递归结束条件
        final = compute(expression)
        return final    # 则结束此函数并执行compute函数
    content = re.search('\(([\+\-\*\/]*\d+\.*\d*){2,}\)', expression).group()  # 如有括号,获取第一个括号中内容

    before, nothing, after = re.split('\(([\+\-\*\/]*\d+\.*\d*){2,}\)', expression, 1)

    print('before:', expression)

    content = content[1:len(content) - 1]  # 获取除了括号中的内容

    ret = compute(content)  # 计算括号中等式

    print('%s=%s' % (content, ret))  # 括号中等式 = 计算结果

    expression = "%s%s%s" % (before, ret, after)  # 重新赋值expression,计算结果代替了括号
    print('after:', expression)   # 替代后的表达式
    print("=" * 10, '上一次计算结束', "=" * 10)
    return exec_bracket(expression)  # 第一个括号消除,继续消除第二个括号,知道原等式中没有括号,就执行compute函数


if __name__ == "__main__":   # 运行程序
    inpp = "1-2*((60-30   +(-40/5   )*(9-2*5/3+7/3*99   /4*2998+10*568/14))-(-4*3)/(16-3*2))"
    inpp = re.sub('\s*', '', inpp)  # 把inpp中的空白符替换成空字符
    result = exec_bracket(inpp)
    print(result)

正则表达式匹配括号
python写计算器