计算器

python计算器

环境:

  • python 3*
  • pycharm

用户需求 :

  • 实现加减乘除及拓号优先级解析:
    • 用户输入 >>>
      1 - 2 * ( (60-30 +(-40/5) * (9-25/3 + 7 /399/42998 +10 * 568/14 )) - (-43)/ (16-3*2) )
      等类似公式后,计算结果

  • 分析:
    解析里面的(),+,-,*,/符号和公式,运算后得出结果,结果必须与真实的计算器>所得出的结果一致
    • 思路:
      1、匹配最里层括号中的内容
      2、逐步计算

    • 细节:
      1、多余空格处理
      2、算数表达式的合法性
      3、处理 ‘++’、 ‘–’、 ‘±’、 ‘-+’、 ‘+’、 ‘+’ …


re 模块学习笔记



程序

# Author:  Langkye
# Data:    2019/9/24

import re

# 检查表达式的合法性
def check_expression(s):
    check_result = True
    if not s.count('(') == s.count(')'):    # 左括号和右括号是否一致
        print('Expression error . Missing ")" of "("')  # 缺失 左括号 或者 右括号
        check_result = False
    if re.findall(r'[^0-9+\-\*/()\s]+',s.lower()):   # 判断表达式是否含有 一个或多个 字母、特殊字符 r'[^0-9+\-\*/()\s]+'  #|#   一个或多个字母集[a-zA-Z]+
        print('Expression Error . Exist other character')       # 表达式包含其它字符
        check_result = False
    return check_result

# 规范化表达式
def format_string(s):
    s = s.replace('--','+')
    s = s.replace('++','+')
    s = s.replace('-+','-')
    s = s.replace('+-','-')
    s = s.replace('*+','*')
    s = s.replace('+*','*')
    s = s.replace('/+','/')
    s = s.replace('+/','/')
    s = s.replace(' ','')
    return s

# 乘除法
def calc_mul_div(s):
    # re 规则
    regular = '\d+\.?\d*([*/]|[\*\*])[\-]?\d+\.?\d*'
    while re.findall(regular,s):
        expression = re.search(regular,s).group()   # 找出满足 乘、除 法规则的第一个结果
        if expression.count('*') == 1:      # 计算乘法
            x, y = expression.split('*')
            mul_result = str(float(x) * float(y))
            s = s.replace(expression,mul_result)  # 将计算结果 ,替换原先的表达式
            s = format_string(s)    # 规范化 ‘++’

        if expression.count('/'): 	# 计算除法
            x, y = expression.split('/')
            div_result = str(float(x) / float(y))
            s = s.replace(expression,div_result)
            s = format_string(s)

        if expression.count('**'):		# 计算幂
            x, y = expression.split()
            pow_result = 1
            for i in range(int(y)):
                pow_result *= int(x)
            s = s.replace(expression,str(pow_result))
            s = format_string(s)
    return s

# 加减法
def calc_add_sub(s):
	# 加法正则 # 匹配 x + y :x、y可为任意有理数 # [\-]? :0或1个“-” ;\d+ :1或多个数字;\.? :0或1个小数点 ; \d* :0或多个数字 ; \d+ :1或多个数字 ; \.? 0或1个小数点 ; \d* :0或多个数字
    add_regular = '[\-]?\d+\.?\d*\+[\-]?\d+\.?\d*'	
    # 减法正则 # 同理 匹配 x - y
    sub_regular = '[\-]?\d+\.?\d*\-[\-]?\d+\.?\d*'

    while re.findall(add_regular,s): # 计算加法
        add_list = re.findall(add_regular,s)
        for add_str in add_list:
            x, y = add_str.split('+')
            add_result = '+' + str(float(x) + float(y))
            s = s.replace(add_str,add_result)
        s = format_string(s)

    while re.findall(sub_regular,s): # 计算减法
        sub_list = re.findall(sub_regular,s)
        for sub_str in sub_list:
            numbers = sub_str.split('-')
            if len(numbers) == 3:
                result = 0
                for v in numbers:
                    if v:
                        result -= float(v)
            else:
                x, y = numbers
                result = float(x) - float(y)
            s = s.replace(sub_str,'+'+str(result))
        s = format_string(s)
    return s

# 主函数
def main(expression = ''):
    if check_expression(expression):
        print('source:\t',expression)
        print('最终结果:',eval(expression))
        source = format_string(expression)
        print('格式化:\t',source)
        num = 1
        while source.count('(') > 0:
            # 取出里层括号内的表达式
            strs = re.search('\([^()]*\)',source).group()   # --------------------------
            replace_str = calc_mul_div(strs)        # -----------------------------------
            replace_str = calc_add_sub(replace_str)        # ----------------------------
            replace_str=format_string(replace_str)
            source = format_string(source.replace(strs,replace_str[1:-1]))      # ----------------
        else:
            replace_str = calc_mul_div(source)
            replace_str = calc_add_sub(replace_str)
            source = source.replace(source,replace_str)
        print('计算结果:',source.replace('+',''))

if __name__ == '__main__':

    # source = '1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 ))    - (-4*3)/ (16-3*2) )'
    # source = '1+1'
    while True:
        source = input('\n%sEnter an expression%s\nEnter [Q] to Exit\n>>>'%('-'*20, '-'*20))
        if source == 'q' or source == 'Q':
            break
        else:
            main(source)

?

—END—

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值