python——简易计算器

简易计算器:

思路:借鉴http://www.cnblogs.com/wushank/p/5172792.html(凯子的博客)

注:完整的简易计算器请点击以上连接

该简易计算器不能计算"1-(-40/5)"此类表达式

逻辑图如下:

'''
该计算器思路:
    1、递归寻找表达式中只含有 数字和运算符的表达式,并计算结果
    2、由于整数计算会忽略小数,所有的数字都认为是浮点型操作,以此来保留小数
使用技术:
    1、正则表达式
    2、递归
执行流程如下:
******************** 请计算表达式: 1 - 2 * ( (60-30 +(-40.0/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) ) ********************
before: ['1-2*((60-30+(-40.0/5)*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))']
-40.0/5=-8.0
after: ['1-2*((60-30+-8.0*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))']
========== 上一次计算结束 ==========
before: ['1-2*((60-30+-8.0*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))']
9-2*5/3+7/3*99/4*2998+10*568/14=173545.880953
after: ['1-2*((60-30+-8.0*173545.880953)-(-4*3)/(16-3*2))']
========== 上一次计算结束 ==========
before: ['1-2*((60-30+-8.0*173545.880953)-(-4*3)/(16-3*2))']
60-30+-8.0*173545.880953=-1388337.04762
after: ['1-2*(-1388337.04762-(-4*3)/(16-3*2))']
========== 上一次计算结束 ==========
before: ['1-2*(-1388337.04762-(-4*3)/(16-3*2))']
-4*3=-12.0
after: ['1-2*(-1388337.04762--12.0/(16-3*2))']
========== 上一次计算结束 ==========
before: ['1-2*(-1388337.04762--12.0/(16-3*2))']
16-3*2=10.0
after: ['1-2*(-1388337.04762--12.0/10.0)']
========== 上一次计算结束 ==========
before: ['1-2*(-1388337.04762--12.0/10.0)']
-1388337.04762--12.0/10.0=-1388335.84762
after: ['1-2*-1388335.84762']
========== 上一次计算结束 ==========
我的计算结果: 2776672.69524
'''
import re
import sys

# 1-2*((60-30+(40.0/5)*(9-2*5/3+7/3*99/4*29+10*8/14))-(4*3)/(16-3*2))


def multiplication_division(args):
    """ 操作乘除"""
    val = args[0]
    patt = '\d+\.?\d*[\*\/\%\/\/]+[\+\-]?\d+\.*\d*'
    m = re.search(patt, val)
    if m is None:
        return
    content = m.group()

    if len(content.split('*')) > 1:
        n1, n2 = content.split('*')
        value = float(n1) * float(n2)
    elif len(content.split('/')) > 1:
        n1, n2 = content.split('/')
        value = float(n1) / float(n2)
    else:
        pass

    before, after = re.split(patt, val, 1)
    new_str = "%s%s%s" % (before, value, after)
    args[0] = new_str
    multiplication_division(args)


def addition_subtraction(args):
    """ 操作加减 """
    val = args[0]
    patt = '\d+\.?\d*[\+\-]{1}\d+\.?\d*'
    m = re.search(patt, val)
    if m is None:
        return
    content = m.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(patt, val, 1)
    new_str = "%s%s%s" % (before, value, after)
    args[0] = new_str
    addition_subtraction(args)


def calcium(calculate_value):
    """ 操作加减乘除 """
    args = [calculate_value, 0]

    # 处理表达式中的乘除
    multiplication_division(args)

    # 处理表达式中的加减
    addition_subtraction(args)
    if divmod(inp[1], 2)[1] == 1:
        result = float(args[0])
    else:
        result = float(args[0])
    return result


def exec_bracket(calculate_value):
    """ 递归处理括号,并计算 """
    patt = '\(([\+\-\*\/\%\/\/\*\*]*\d+\.*\d*){2,}\)'
    # 如果表达式中已经没有括号,则直接调用负责计算的函数,将表达式结果返回
    if not re.search(patt, calculate_value):
        final = calcium(calculate_value)
        return final
    # 获取括号内的数据
    content = re.search(patt, calculate_value).group()

    # 分割表达式,分成三部分
    before, nothing, after = re.split(patt, calculate_value, 1)

    # 处理前
    print('处理前:', calculate_value)
    content = content[1:len(content)-1]

    # 计算,提取的表示 (-40.0/5),并活的结果,即:-40.0/5=-8.0
    ret = calcium(content)

    print('%s=%s' % (content, ret))

    # 将执行结果拼接
    calculate_value = "%s%s%s" % (before, ret, after)

    print('处理后:', calculate_value)
    print("*"*10, '结果展示如下', "*"*10)

    # 使用递归,循环处理括号内的数据,直到没有括号
    return exec_bracket(calculate_value)

if __name__ == "__main__":

    print('*'*50)
    print(' '*15, '我的简易计算器')
    print('*'*50)

    while True:
        calculate_value = input('请输入计算的表达式(不支持"1-(-40/5)"此类表达式)(退出:q)')
        # sub()将字符串中所有匹配正则表达式模式的部分进行替换,去掉空格
        calculate_value = re.sub('\s*', '', calculate_value)
        if len(calculate_value) == 0:
            continue
        elif calculate_value == 'q':
            sys.exit('退出程序')
        elif re.search('[^0-9\.\-\+\*\/\*\*\(\)]', calculate_value):
            print('输入错误,请检查输入表达式是否正确!')
        else:
            result = exec_bracket(calculate_value)
            print('输出结果:%s' % result)
简易计算器

运行效果如下:

posted on 2016-02-17 15:51  揉碎的青春  阅读(422)  评论(0编辑  收藏  举报

导航