实用的Python计算器全解·py库运用(含完整代码),支持绝对值和程序员模式

Python智能数学求解器实现

摘要:本文介绍了一个智能数学问题求解器的Python实现,支持分数方程求解、等差数列求和及表达式化简。程序使用SymPy库精确处理分数运算,可解析带省略号的等差数列求和(如1+2+...+100),并支持分数方程的精确求解(如(1/2)x=3/4)。系统提供分数和小数两种结果形式,具有错误检测功能,能识别无效输入。实现包含输入标准化、符号处理、分数转换等核心功能,通过正则表达式和eval安全执行实现灵活解析。该工具适用于数学学习辅助,能有效保持分数运算的精确性。

import sympy as sp
import re
from sympy import Rational, simplify, pretty

def parse_ellipsis_expression(expr_str):
    """解析带省略号的表达式,处理等差数列求和"""
    expr_str = expr_str.replace('···', '...').replace('…', '...')
    
    if '...' not in expr_str:
        return None
    
    parts = expr_str.split('...')
    if len(parts) != 2:
        return f"错误:表达式中省略号使用不当,只能有一个省略号"
    
    left_part, right_part = parts
    
    # 提取左侧的数字(取最后一个数字作为起始点)
    left_numbers = re.findall(r'(\d+\.?\d*)', left_part)
    if not left_numbers:
        return f"错误:省略号左侧没有有效的数字"
    start = float(left_numbers[-1])
    
    # 提取右侧的数字(取第一个数字作为结束点)
    right_numbers = re.findall(r'(\d+\.?\d*)', right_part)
    if not right_numbers:
        return f"错误:省略号右侧没有有效的数字"
    end = float(right_numbers[0])
    
    # 确定公差
    if len(left_numbers) >= 2:
        prev = float(left_numbers[-2])
        step = start - prev
    else:
        step = 1  # 默认公差为1
    
    # 验证序列有效性
    if (end - start) * step < 0:
        return f"错误:数列方向不一致(公差与起止方向相反)"
    
    if step == 0:
        return f"错误:数列公差不能为0"
    
    # 计算项数和总和
    n = int((end - start) / step) + 1
    total = n * (start + end) / 2
    
    # 构建解释文本
    explanation = f"计算 {start} + {start+step} + ... + {end} 的和:\n"
    explanation += f"- 首项 a₁ = {start}\n"
    explanation += f"- 末项 aₙ = {end}\n"
    explanation += f"- 公差 d = {step}\n"
    explanation += f"- 项数 n = {n}\n"
    explanation += f"- 总和 = n×(a₁+aₙ)/2 = {n}×({start}+{end})/2 = "
    
    if total.is_integer():
        return explanation + f"{int(total)}"
    else:
        fraction = sp.Rational(total).limit_denominator()
        return explanation + f"{total}(分数形式:{fraction})"

def solve_fraction_equation(expr_str):
    """专门处理含分数的方程,保持分数精确性"""
    # 替换并标准化方程中的符号
    expr_str = expr_str.replace('×', '*').replace('÷', '/')
    expr_str = expr_str.replace('^', '**')
    # 处理数字与变量相连的情况(如2x或(1/2)x)
    expr_str = re.sub(r'(\d)([a-zA-Z])', r'\1*\2', expr_str)
    expr_str = re.sub(r'(\))([a-zA-Z])', r'\1*\2', expr_str)  # 处理(1/2)x → (1/2)*x
    expr_str = re.sub(r'([a-zA-Z])(\d)', r'\1*\2', expr_str)  # 处理x2 → x*2
    
    # 检查是否是方程
    if '=' not in expr_str:
        return None
    
    left, right = expr_str.split('=', 1)
    left = left.strip()
    right = right.strip()
    
    # 查找变量(假设一元方程)
    variables = list(set(re.findall(r'[a-zA-Z]', expr_str)))
    if len(variables) != 1:
        return None
    
    var = variables[0]
    x = sp.Symbol(var)
    
    try:
        # 处理分数,将a/b形式转换为Rational(a,b)
        def replace_fraction(match):
            return f'Rational({match.group(1)},{match.group(2)})'
        
        left = re.sub(r'(\d+)/(\d+)', replace_fraction, left)
        right = re.sub(r'(\d+)/(\d+)', replace_fraction, right)
        
        # 构建方程
        left_expr = eval(left, {'__builtins__': None, 'Rational': Rational}, {var: x})
        right_expr = eval(right, {'__builtins__': None, 'Rational': Rational}, {var: x})
        equation = sp.Eq(left_expr, right_expr)
        
        # 求解并保持分数形式
        solution = sp.solve(equation, x)
        
        if solution:
            sol = solution[0]
            # 确保结果为分数形式
            if isinstance(sol, float):
                sol = Rational(sol).limit_denominator()
            
            # 同时展示分数和小数形式
            return (f"{var} = {sol}\n"
                   f"分数形式: {pretty(sol, use_unicode=True)}\n"
                   f"小数形式: {float(sol)}")
        else:
            return f"该方程无解"
            
    except Exception as e:
        return f"分数方程解析出错: {str(e)}\n提示:请使用正确的分数格式,如(1/2)x = 3/4"

def solve_math_problem(input_str):
    """解决数学问题,增强方程中的分数运算支持"""
    input_str = input_str.strip()
    
    # 先检查是否是带省略号的表达式
    ellipsis_result = parse_ellipsis_expression(input_str)
    if ellipsis_result is not None:
        return ellipsis_result
    
    # 尝试用分数方程求解器处理
    fraction_eq_result = solve_fraction_equation(input_str)
    if fraction_eq_result is not None:
        return fraction_eq_result
    
    # 通用处理
    input_str = input_str.replace('×', '*').replace('÷', '/')
    input_str = input_str.replace('^', '**').replace('=', '==')
    input_str = re.sub(r'(\d)([a-zA-Z])', r'\1*\2', input_str)
    input_str = re.sub(r'(\d+)/(\d+)', r'Rational(\1, \2)', input_str)
    
    namespace = {'sp': sp, 'Rational': Rational, 'simplify': simplify}
    
    if '==' in input_str:
        try:
            variables = list(set(re.findall(r'[a-zA-Z]', input_str)))
            
            if variables:
                exec(f"{', '.join(variables)} = {', '.join([f'sp.Symbol(\"{v}\")' for v in variables])}", namespace)
            
            left, right = input_str.split('==', 1)
            left_expr = eval(left.strip(), namespace)
            right_expr = eval(right.strip(), namespace)
            equation = sp.Eq(left_expr, right_expr)
            
            results = []
            for var in variables:
                solution = sp.solve(equation, namespace[var], dict=True)
                if solution:
                    formatted_solution = []
                    for sol in solution:
                        val = sol[namespace[var]]
                        # 转换为分数形式
                        if isinstance(val, float):
                            val = Rational(val).limit_denominator()
                        formatted_solution.append(f"{val}(即{float(val)})")
                    results.append(f"{var} = {', '.join(formatted_solution)}")
            
            if not results:
                return "该方程无解或无法求解"
            else:
                return "\n".join(results)
                
        except Exception as e:
            return f"方程求解出错: {str(e)}\n提示:分数方程请使用格式如(1/2)x + 3/4 = 5/6"
    
    else:
        try:
            variables = list(set(re.findall(r'[a-zA-Z]', input_str)))
            
            if variables:
                exec(f"{', '.join(variables)} = {', '.join([f'sp.Symbol(\"{v}\")' for v in variables])}", namespace)
                expr = eval(input_str, namespace)
                simplified = simplify(expr)
                return f"表达式化简结果: {simplified}\n(分数形式: {pretty(simplified, use_unicode=True)})"
            else:
                result = eval(input_str, namespace)
                fraction_result = sp.Rational(result).limit_denominator()
                return f"计算结果: {result}\n分数形式: {fraction_result} ({pretty(fraction_result, use_unicode=True)})"
                
        except Exception as e:
            return f"表达式计算出错: {str(e)}\n提示:分数请用a/b形式,如1/2+3/4"

def main():
    print("智能自动题目解答器 (分数方程增强版)")
    print("支持功能:")
    print("1. 分数表达式计算 (例如: 1/2 + 3/4, (2/3)*(5/6))")
    print("2. 含分数的方程求解 (例如: (1/2)x = 3/4, x + 1/3 = 5/6)")
    print("3. 普通方程求解 (例如: 2x=10, x+5=3x-1)")
    print("4. 带省略号的等差数列求和 (例如: 1+2+3+...+100)")
    print("-" * 50)
    
    while True:
        user_input = input("请输入算式或方程: ")
        
        if user_input.lower() == 'exit':
            print("谢谢使用,再见!")
            break
            
        if not user_input.strip():
            continue
            
        result = solve_math_problem(user_input)
        print(f"解: {result}\n")

if __name__ == "__main__":
    main()
    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值