Python 计算器练手

初学python,拿计算器练练手

版本python3.9

import re

"""
    计算器demo
"""


def inp(s):
    """ 计算入口,传入一个字符串,如:(((489-8)/9)+9-(985*(76-2)))*89 """

    check(s)  # 校验字符串是否合法
    strRE = r'(?<=\()[^()]*(?=\))'
    # 查找括号内容
    brackets = re.findall(strRE, s)
    # 如果有括号就计算括号内的
    while len(brackets) > 0:
        for ss in brackets:
            s = s.replace('(-)'.replace('-', ss), str(calcNoBrackets(ss)))
        brackets = re.findall(strRE, s)
    return calcNoBrackets(s)  # 没有括号之后,计算并返回最终结果


def calcNoBrackets(s):
    """ 传入一个字符串,不包含括号,如:5-9+8*5+85*76/42-1*-8 """

    reStr = r'\d+([.]\d+)?[*/][-]*\d+([.]\d+)?'
    res = re.search(reStr, s)
    while res is not None:
        sr = s[res.regs[0][0]:res.regs[0][1]]
        s = s.replace(sr, str(calcTwoNum(sr)), 1)
        res = re.search(reStr, s)
    reStr = r'-*\d+([.]\d+)?[+-][-]*\d+([.]\d+)?'
    res = re.search(reStr, s)
    while res is not None:
        sr = s[res.regs[0][0]:res.regs[0][1]]
        s = s.replace(sr, str(calcTwoNum(sr)), 1)
        res = re.search(reStr, s)
    return s


def calcTwoNum(s):
    i = re.search(r'(?<=\d)[*\-/+]', s).regs[0][0]
    a = transToNum(s[:i])
    b = transToNum(s[i+1:])
    operator = s[i]
    if operator == '*':
        return a * b
    if operator == '/':
        return a / b
    if operator == '+':
        return a + b
    if operator == '-':
        return a - b


def transToNum(s):
    """ 字符串转数字 """
    if s.isnumeric():
        return int(s)
    # 处理负数
    elif len(s) > 1 and s[1:].isnumeric() and s[0] == '-':
        return int(s)
    # 处理小数
    else:
        return float(s)


def check(s):
    """
    校验字符串是否可用
    """
    res = re.findall('[-+/*0-9().]', s)
    if len(res) != len(s):
        raise ValueError('unusable str:{}'.format(s))
    res = len(re.findall('[/*+-][/*+]', s))
    res += len(re.findall('[(][/*+]', s))
    res += len(re.findall('[/*+-][)]', s))
    res += len(re.findall('[)][0-9]', s))
    res += len(re.findall('[0-9][(]', s))
    res += len(re.findall('[(][)]', s))
    if res > 0:
        raise ValueError('unusable str:{}'.format(s))
    return True

猜你喜欢

转载自blog.csdn.net/BDawn/article/details/109603722