Python实现高级计算器:从基础到复杂计算的旅程

本文介绍了如何使用Python实现一个基础计算器,逐步扩展到处理更复杂的数学运算,如三角函数、指数运算,并增加了解方程和安全评估函数的功能。
摘要由CSDN通过智能技术生成

基础篇:构建一个简单的计算器

我们来创建一个可以进行加、减、乘、除运算的计算器。

# 定义一个函数,用于计算表达式的值  
def calculate(expression):  
    try:  
        result = eval(expression)  
        return result  
    except:  
        return "Error: Invalid expression"  
  
# 定义一个函数,用于获取用户输入的表达式  
def get_expression():  
    expression = input("Enter an expression: ")  
    return expression  
  
# 定义一个函数,用于显示结果  
def display_result(result):  
    print("Result:", result)  
  
# 主程序  
while True:  
    expression = get_expression()  
    result = calculate(expression)  
    display_result(result)

再复杂一点呢?

进阶篇:处理更复杂的数学功能

在掌握了基础运算之后,我们将深入到更复杂的数学函数。我们将学习如何使用Python的数学库来处理三角函数、指数函数等

import re
import math

operatorDict ={
    '+': lambda a, b: float(a)+float(b),
    '-': lambda a, b: float(a)-float(b),
    '*': lambda a, b: float(a)*float(b),
    '/': lambda a, b: float(a)/float(b),
    '^': lambda a, b: float(a)**float(b),
}

# 计算表达式的值
def calculate(expression):

    # 计算去括号后表达式的值
    def calBrackets(expre):
        for i in operatorDict:
            expre = expre.replace(i, 's'+i+'s')
        l = expre.split('s')  # 表达式转化为数字运算符列表
        # 将-和数字组合在一起
        l2, i = [], 0
        while i < len(l):
            # 处理负数
            if l[i] == '':  # 负号开头或者负号与其他运算符连在一起,splite后会为'',例如 -5*-2  ['','-','5','*','','-','2']
                l2.append(l[i+1]+l[i+2])   # 将符号和数字合一起  -2
                i += 2
            else:
                l2.append(l[i])
            i += 1
        # l2为新数字运算符列表(处理符号后,例['-1', '+', '*', '-3'])
        # 运算乘除
        i = 1
        while i < len(l2):  # 计算乘除
            if l2[i] in ['*', '/', '^']:
                # 将符号左右以及符号三个元素替换为运算结果,必须是个列表, list[m:n] :切片取值连续,不包括n
                l2[i-1:i+2] = [operatorDict[l2[i]](l2[i-1], l2[i+1])]  # 运算
            else:
                i += 2
        # 运算加减,直接按顺序计算替换
        while len(l2) > 1:
            l2[0:3] = [operatorDict[l2[1]](l2[0], l2[2])]
        return str(l2[0])

    # 去除空格
    expression = expression.replace(' ', '')

    # 正则匹配表达式是否包含括号    [^\(\)] : 匹配不是( 或者) 的内容,即非括号内容
    check = re.search('\([^\(\)]+\)', expression)  # 返回匹配到的内容,带括号,只返回一个
    # 去掉括号
    while check:
        checkValue = check.group()
        # 将匹配到的括号表达式替换成值,括号去掉使用函数求值
        expression = expression.replace(checkValue, calBrackets(checkValue[1:-1]))
        check = re.search('\([^\(\)]*\)', expression)

    else:
        return calBrackets(expression)
    

# 让计数器支持用户循环输入,输入q退出循环
while True:
    expression = input('请输入要计算的表达式(输入q退出): ')
    expression = expression.lower()

    if expression == 'q':
        print('退出计算器')
        break

    try:
        # 添加计算功能
        if 'pi' in expression:
            expression = expression.replace('pi', str(math.pi))
        if 'sin' in expression:
            # 使用math库计算sin
            expression = re.sub('sin\((.*?)\)', lambda x: str(math.sin(math.radians(float(x.group(1))))), expression)
        if 'cos' in expression:
            # 使用math库计算cos
            expression = re.sub('cos\((.*?)\)', lambda x: str(math.cos(math.radians(float(x.group(1))))), expression)
        result = calculate(expression)
        print(result)
    except Exception as e:
        print('表达式不合法,请重新输入;错误信息:', e)

使用效果

做成函数使用

另外还加入了tan和e运算

import re
import math

operatorDict = {
    '+': lambda a, b: float(a) + float(b),
    '-': lambda a, b: float(a) - float(b),
    '*': lambda a, b: float(a) * float(b),
    '/': lambda a, b: float(a) / float(b),
    '^': lambda a, b: float(a) ** float(b),
}

# 计算表达式的值
def calculate(expression):

    # 计算去括号后表达式的值
    def calBrackets(expre):
        for i in operatorDict:
            expre = expre.replace(i, 's' + i + 's')
        l = expre.split('s')  # 表达式转化为数字运算符列表
        # 将-和数字组合在一起
        l2, i = [], 0
        while i < len(l):
            # 处理负数
            if l[i] == '':  # 负号开头或者负号与其他运算符连在一起,splite后会为'',例如 -5*-2  ['','-','5','*','','-','2']
                l2.append(l[i+1] + l[i+2])   # 将符号和数字合一起  -2
                i += 2
            else:
                l2.append(l[i])
            i += 1
        # l2为新数字运算符列表(处理符号后,例['-1', '+', '*', '-3'])

        # 运算乘除
        i = 1
        while i < len(l2):  # 计算乘除
            if l2[i] in ['*', '/', '^']:
                # 将符号左右以及符号三个元素替换为运算结果,必须是个列表, list[m:n] :切片取值连续,不包括n
                l2[i-1:i+2] = [operatorDict[l2[i]](l2[i-1], l2[i+1])]  # 运算
            else:
                i += 2

        # 运算加减,直接按顺序计算替换
        while len(l2) > 1:
            l2[0:3] = [operatorDict[l2[1]](l2[0], l2[2])]

        return str(l2[0])

    # 处理数学函数
    def handle_math_functions(expr):
        if 'sin(' in expr:
            expr = re.sub('sin\((.*?)\)', lambda x: str(math.sin(math.radians(float(x.group(1))))), expr)
        if 'cos(' in expr:
            expr = re.sub('cos\((.*?)\)', lambda x: str(math.cos(math.radians(float(x.group(1))))), expr)
        if 'tan(' in expr:
            expr = re.sub('tan\((.*?)\)', lambda x: str(math.tan(math.radians(float(x.group(1))))), expr)
        if 'pi' in expr:
            expr = expr.replace('pi', str(math.pi))
        if 'e' in expr:
            expr = expr.replace('e', str(math.e))
        return expr

    try:
        expression = handle_math_functions(expression)
        # 去除空格
        expression = expression.replace(' ', '')
        # 正则匹配表达式是否包含括号
        check = re.search(r'\([^()]*\)', expression)

        # 去掉括号
        while check:
            checkValue = check.group()
            # 将匹配到的括号表达式替换成值, 括号去掉使用函数求值
            expression = expression.replace(checkValue, calBrackets(checkValue[1:-1]))
            check = re.search(r'\([^()]*\)', expression)
        else:
            return calBrackets(expression)
    except Exception as e:
        print(f'表达式输入错误: {e}')

#调用示例
print(calculate("sin(30)"))
print(calculate("cos(60)"))
print(calculate("tan(60)"))
print(calculate("2e")) 
print(calculate("2*pi"))
print(calculate("2+(2-2^3)"))
print(calculate("1/2 + 2/1"))#分数计算

函数使用效果

函数调用示例

from calculator import calculate

result=(calculate("2+2-1"))
print((result))

#代码输出3.0

高级篇:构建一个复杂计算器

增加解方程功能

先安装必要库 

pip install sympy
import sympy as sp

def solve_equation(equation):
    x = sp.symbols('x')
    try:
        # 将等式转换为标准形式 ax + b = 0
        if '=' in equation:
            equation = equation.replace('=', '-(') + ')'
        equation = equation.replace('*', '*')  # 确保乘法符号正确
        equation = equation.replace(' ', '')  # 移除空格
        equation = sp.sympify(equation)  # 将字符串转换为符号表达式
        solutions = sp.solve(equation, x)  # 解方程
        return solutions
    except (sp.SympifyError, SyntaxError) as e:
        print(f"Error: 无法解析方程 '{equation}'. 请检查方程格式是否正确.")
        return None
    except Exception as e:
        print(f"Error: 未知错误 '{e}'.")
        return None

# 调用解方程的示例
linear_equation = "2*x + 3 -  7=1"  # 一元一次方程,等号右侧移到左侧
quadratic_equation = "x**2 - 5*x + 6"  # 一元二次方程

print(solve_equation(linear_equation))  # 输出: [5/2]
print(solve_equation(quadratic_equation))  # 输出: [2, 3]

增加函数功能

import ast
import operator

class SafeCalculator:
    def __init__(self):
        self.variables = {}
        self.formula = None

    def set_variable(self, var, value):
        self.variables[var] = value

    def set_formula(self, formula):
        self.formula = formula

    def evaluate(self):
        if not self.formula:
            return "No formula set!"
        
        # Replace variables in the formula with their values
        for var, val in self.variables.items():
            self.formula = self.formula.replace(var, str(val))
        
        # Extract the right side of the equation for evaluation
        if "=" in self.formula:
            _, expression = self.formula.split("=", 1)
        else:
            expression = self.formula
        
        # Use a custom function to safely evaluate the expression
        try:
            result = self.custom_eval(expression.strip())
            return result
        except Exception as e:
            return f"Error: {e}"

    def custom_eval(self, expression):
        def eval_expression(expression):
            if expression.isdigit():
                return int(expression)
            
            # Handle parentheses first
            if expression.startswith("(") and expression.endswith(")"):
                return eval_expression(expression[1:-1])
            
            # Handle basic operations in order of precedence
            if "^" in expression:
                base, exp = map(str.strip, expression.split("^", 1))
                return eval_expression(base) ** eval_expression(exp)
            if "*" in expression or "/" in expression:
                terms = expression.split()
                result = eval_expression(terms[0])
                for i in range(1, len(terms), 2):
                    if terms[i] == "*":
                        result *= eval_expression(terms[i+1])
                    elif terms[i] == "/":
                        result /= eval_expression(terms[i+1])
                return result
            if "+" in expression or "-" in expression:
                terms = expression.split()
                result = eval_expression(terms[0])
                for i in range(1, len(terms), 2):
                    if terms[i] == "+":
                        result += eval_expression(terms[i+1])
                    elif terms[i] == "-":
                        result -= eval_expression(terms[i+1])
                return result
            
            # If no operations are found, it should be a number or a variable
            try:
                return int(expression)
            except ValueError:
                try:
                    return float(expression)
                except ValueError:
                    return self.variables[expression]

        return eval_expression(expression)

# 示例
calc = SafeCalculator()
calc.set_formula("s = a + b * c - 4 ** 2") #设置函数
calc.set_variable("a", 5) #设置字母的值
calc.set_variable("b", 6)
calc.set_variable("c", 9)
result = calc.evaluate() #计算函数值输出35
print(result)

  • 9
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值