【Python】方程计算器

安装依赖

requirements.txt:

复制代码
sympy>=1.12
rich>=13.0
PyQt6>=6.0
matplotlib>=3.5

安装:

bash 复制代码
pip install -r requirements.txt

源代码

python 复制代码
from sympy import symbols, sympify, solve, Eq, S, Rational, sqrt
from sympy.parsing.sympy_parser import parse_expr, standard_transformations, implicit_multiplication_application
from rich.console import Console
from rich.panel import Panel
from rich.table import Table
from rich.text import Text
from rich.prompt import Prompt
from rich import print as rprint
import re
import random

console = Console()

transformations = standard_transformations + (implicit_multiplication_application,)

def display_welcome():
    welcome_text = Text()
    welcome_text.append("🧮 ", style="bold yellow")
    welcome_text.append("方程计算器", style="bold cyan")
    welcome_text.append(" - 欢迎使用! ", style="bold white")
    welcome_text.append("🧮", style="bold yellow")
    
    panel = Panel(
        welcome_text,
        title="[bold magenta]✨ 交互式方程求解器 ✨[/bold magenta]",
        title_align="center",
        border_style="bright_blue",
        padding=(1, 2)
    )
    console.print(panel)
    
    console.print("\n[green]📌 功能说明:[/green]")
    console.print("  • 支持输入多个方程(用分号 ; 分隔)")
    console.print("  • 支持指定变量(用逗号 , 分隔)")
    console.print("  • 最多显示 10 组解")
    console.print("  • 输入 'example' 获取随机方程示例")
    console.print("  • 输入 'quit' 或 'exit' 退出程序")
    console.print("\n[yellow]📌 注意事项:[/yellow]")
    console.print("  • 乘法必须用 * (如: 3*x)")
    console.print("  • 幂运算用 ** (如: x**2)\n")

def generate_linear_equation():
    a = random.randint(1, 10)
    b = random.randint(-10, 10)
    c = random.randint(-10, 10)
    equation = f"{a}*x + {b} = {c}"
    variables = "x"
    return equation, variables

def generate_quadratic_equation():
    a = random.randint(1, 5)
    b = random.randint(-10, 10)
    c = random.randint(-10, 10)
    equation = f"{a}*x**2 + {b}*x + {c} = 0"
    variables = "x"
    return equation, variables

def generate_cubic_equation():
    a = random.randint(1, 3)
    b = random.randint(-5, 5)
    c = random.randint(-10, 10)
    d = random.randint(-10, 10)
    equation = f"{a}*x**3 + {b}*x**2 + {c}*x + {d} = 0"
    variables = "x"
    return equation, variables

def generate_linear_system():
    a1 = random.randint(1, 5)
    b1 = random.randint(1, 5)
    c1 = random.randint(1, 10)
    a2 = random.randint(1, 5)
    b2 = random.randint(1, 5)
    c2 = random.randint(1, 10)
    equation = f"{a1}*x + {b1}*y = {c1}; {a2}*x + {b2}*y = {c2}"
    variables = "x,y"
    return equation, variables

def generate_quadratic_system():
    a = random.randint(1, 3)
    b = random.randint(1, 3)
    c = random.randint(1, 10)
    d = random.randint(1, 3)
    e = random.randint(1, 3)
    f = random.randint(1, 10)
    equation = f"x + y = {c}; x*y = {f}"
    variables = "x,y"
    return equation, variables

def generate_random_example():
    examples = [
        ("一次方程", generate_linear_equation),
        ("二次方程", generate_quadratic_equation),
        ("三次方程", generate_cubic_equation),
        ("一次方程组", generate_linear_system),
        ("二次方程组", generate_quadratic_system)
    ]
    
    choice = random.choice(examples)
    equation, variables = choice[1]()
    return choice[0], equation, variables

def display_examples():
    console.print("\n" + "="*50)
    console.print("[bold cyan]🎲 随机生成方程示例 🎲[/bold cyan]")
    console.print("="*50 + "\n")
    
    for i in range(3):
        if i == 2:
            type_name = "复杂三次方程"
            equation, variables = generate_cubic_equation()
        else:
            type_name, equation, variables = generate_random_example()
        console.print(f"[yellow]示例 {i+1} - {type_name}:[/yellow]")
        console.print(f"  方程: [cyan]{equation}[/cyan]")
        console.print(f"  变量: [green]{variables}[/green]\n")
    
    console.print("="*50 + "\n")

def parse_equation(equation_str, variables_str):
    equations = []
    eq_list = [eq.strip() for eq in equation_str.split(';') if eq.strip()]
    
    var_list = [v.strip() for v in variables_str.split(',') if v.strip()]
    var_symbols = symbols(var_list)
    
    for eq in eq_list:
        if '=' in eq:
            left, right = eq.split('=', 1)
            left_expr = parse_expr(left.strip(), transformations=transformations)
            right_expr = parse_expr(right.strip(), transformations=transformations)
            equations.append(Eq(left_expr, right_expr))
        else:
            equations.append(parse_expr(eq.strip(), transformations=transformations))
    
    return equations, var_symbols

def solve_equation(equations, var_symbols):
    try:
        solutions = solve(equations, var_symbols, dict=True)
        return solutions
    except Exception as e:
        console.print(f"[yellow]⚠️  求解过程出错: {str(e)}[/yellow]")
        return None

def display_solutions(solutions, var_symbols):
    if not solutions:
        console.print("\n[red]❌ 无解或无法求解![/red]")
        return
    
    if len(solutions) == 0:
        console.print("\n[red]❌ 方程无解![/red]")
        return
    
    if solutions[0] == {}:
        console.print("\n[yellow]⚠️  方程有无穷多解![/yellow]")
        return
    
    display_count = min(len(solutions), 10)
    
    table = Table(title="[bold cyan]📊 求解结果 📊[/bold cyan]", show_header=True, header_style="bold magenta")
    table.add_column("序号", style="cyan", justify="center", width=6)
    
    for var in var_symbols:
        table.add_column(f"{var}", style="green", justify="center")
    
    for i, sol in enumerate(solutions[:display_count]):
        row = [f"[yellow]{i+1}[/yellow]"]
        for var in var_symbols:
            value = sol.get(var, None)
            if value is None:
                row.append("[red]N/A[/red]")
            else:
                try:
                    from sympy import Rational, nsimplify
                    float_val = float(value)
                    
                    if float_val.is_integer():
                        row.append(f"[green]{int(float_val)}[/green]")
                    else:
                        rational_val = nsimplify(value)
                        if isinstance(rational_val, Rational):
                            numerator = rational_val.p
                            denominator = rational_val.q
                            row.append(f"[green]{float_val:.4f}[/green] [dim]({numerator}/{denominator})[/dim]")
                        else:
                            symbolic_str = str(rational_val)
                            if symbolic_str != str(float_val):
                                row.append(f"[green]{float_val:.4f}[/green] [dim]({symbolic_str})[/dim]")
                            else:
                                row.append(f"[green]{float_val:.4f}[/green]")
                except:
                    row.append(f"[green]{value}[/green]")
        table.add_row(*row)
    
    console.print("\n")
    console.print(table)
    
    if len(solutions) > 10:
        console.print(f"\n[yellow]⚠️  还有 {len(solutions) - 10} 组解未显示...[/yellow]")

def get_user_input(prompt_text, error_msg, validation_func=None):
    while True:
        try:
            user_input = Prompt.ask(prompt_text, console=console).strip()
            if user_input.lower() in ['quit', 'exit']:
                return None
            
            if validation_func and not validation_func(user_input):
                console.print(f"[red]❌ {error_msg}[/red]")
                continue
            
            return user_input
        except KeyboardInterrupt:
            console.print("\n\n[yellow]👋 感谢使用,再见![/yellow]")
            exit(0)

def validate_equation(equation_str):
    if not equation_str or equation_str.isspace():
        return False
    return True

def validate_variables(variables_str):
    if not variables_str or variables_str.isspace():
        return False
    return bool(re.match(r'^[a-zA-Z]+(?:,[a-zA-Z]+)*$', variables_str))

def main():
    display_welcome()
    
    while True:
        console.print("\n" + "="*50)
        
        equation_input = get_user_input(
            "📝 请输入方程(多个方程用分号分隔)",
            "方程不能为空!",
            validate_equation
        )
        
        if equation_input is None:
            console.print("\n[yellow]👋 感谢使用,再见![/yellow]")
            break
        
        if equation_input.lower() == 'example':
            display_examples()
            continue
        
        variables_input = get_user_input(
            "🎯 请输入变量(用逗号分隔)",
            "变量格式不正确! 请使用字母,如: x,y",
            validate_variables
        )
        
        if variables_input is None:
            console.print("\n[yellow]👋 感谢使用,再见![/yellow]")
            break
        
        console.print("\n[yellow]🔍 正在求解...[/yellow]")
        
        try:
            equations, var_symbols = parse_equation(equation_input, variables_input)
            solutions = solve_equation(equations, var_symbols)
            display_solutions(solutions, var_symbols)
        except Exception as e:
            console.print(f"\n[red]❌ 求解出错: {str(e)}[/red]")
        
        console.print("\n" + "-"*50)
        continue_input = Prompt.ask("🔄 继续计算?", console=console, choices=["y", "n"], default="y").strip().lower()
        
        if continue_input != 'y':
            console.print("\n[yellow]👋 感谢使用,再见![/yellow]")
            break

if __name__ == "__main__":
    try:
        main()
    except KeyboardInterrupt:
        console.print("\n\n[yellow]👋 感谢使用,再见![/yellow]")

运行结果:

注意:

乘号使用'* ',除号或分数使用'/ ',幂运算用'**'

相关推荐
枫叶林FYL10 小时前
项目九:异步高性能爬虫与数据采集中枢 —— 基于 Crawl<sub>4</sub>AI 与 Playwright 的现代化数据采集平台 项目总览
爬虫·python·深度学习·wpf
likerhood10 小时前
Java static 关键字从浅入深
java·开发语言
猫猫的小茶馆11 小时前
【Python】函数与模块化编程
linux·开发语言·arm开发·驱动开发·python·stm32
计算机安禾11 小时前
【c++面向对象编程】第38篇:设计原则(二):里氏替换、接口隔离与依赖倒置
开发语言·c++
_院长大人_11 小时前
Java Excel导出:如何实现自定义表头与字段顺序的完全控制
java·开发语言·后端·excel
code_whiter11 小时前
C++1进阶(继承)
开发语言·c++
来恩100311 小时前
JSTL的标签库种类
java·开发语言
Miss_min11 小时前
128K长序列数据生成
开发语言·python·深度学习
love530love11 小时前
MingLi-Bench 项目部署实录:基于 EPGF 架构的工程化实践
人工智能·windows·python·架构·aigc·epgf·mingli-bench
小宋00111 小时前
QT中控件qss样式修改
开发语言·qt