资料详情

Python实现科学计算器 论文

头像

理工论文

编号:10777

目 录

1 问题描述

2 需求分析

2.1 数据需求

2.2 功能需求

3 概要设计

3.1 主体设计

3.2 用户界面设计

3.3抽象数据类型

3.3.1 科学计算器

3.3.2 多项式计算器

3.3.3 历史记录

3.4 功能模块设计

3.4.1 科学计算器

3.4.2多项式计算器:

3.4.3.历史记录

4 详细设计及系统实现

4.1 科学计算器

4.1.1 科学计算器数据结构

4.1.2 科学计算器界面

4.1.3 科学计算机算法实现

4.2多项式计算器

4.2.1 多项式计算器数据结构

4.2.2 多项式计算器界面

4.2.3多项式计算器算法实现

4.3  历史记录

4.3.1 历史记录数据结构

4.3.2 历史记录界面

4.4 程序打包

5 系统调试分析

6 课程设计总结

6.1实现功能

6.2有待改进部分

6.3自我总结

附录:


1 问题描述

设计程序模拟Windows计算器,部分要求如下:

<1>为计算器设计

<2>计算器可以进行基本的计算

<3>计算器可以识别括号,并对常见函数如幂函数、三角函数、对数函数等进行求解

<4>计算器能够保存历史运算表达式,用户可以查看历史运算

<5>计算器可以实现一元多项式的运算

例:设有一元多项式Am(x)和Bn(x):

Am(x)=A0+A1x1+A2x2+A3x3+… +Amxm,

Bn(x)=B0+B1x1+B2x2+B3x3+… +Bnxn.

可求得M(x)= Am(x)+Bn(x)、M(x)= Am(x)-Bn(x)和M(x)= Am(x)×Bn(x),

且M(x)中无重复阶项和无零系数项,并且输出结果有升幂和降幂两种排列情况。

2 需求分析

该演示程序在Python的tkinter库环境中编写,目标是实现一个包含多项式运算功能的科学计算器.

2.1 数据需求

<1>输入数据的形式和范围:在进行普通运算时,数据从按键上输入.在进行多项式运算时,多项式从键盘输入,并通过下拉框选择合适的运算符号进行运算.

<2>输出形式:在输出框内显示运算结果.若输入算式有误,给予用户提示.

2.2 功能需求

<1>需要对Python软件与对应语法具备一定了解.

<2>需要具备基本的编程能力,需了解各个计算器按键的功能.

<3>需要熟练运用正则表达式进行字符串匹配.

3 概要设计

3.1 主体设计

             

图3.1.1计算器功能全局流程

3.2 用户界面设计

<1>科学计算器界面:需包含绝大多数科学计算器中按键,并可通过点击按键引起输入框中的文本变化,同时需要创建多项式计算按键与历史记录查看按键,在呈现简洁性的同时方便用户操作.

<2>多项式计算器界面:需包含两个输入框,用于输入待计算多项式,同时设置符号选择框,限制可用于进行的多项式运算操作.此外,还需设置两个输出框(一个升幂输出,一个降幂输出)和一个历史记录显示按键.

<3>历史记录界面:需包含文本展示框与文本清除按钮.

3.3抽象数据类型

3.3.1 科学计算器

calculator = Tk()
calculator.title("Calculator")

3.4 功能模块设计

3.4.1 科学计算器

1.确定科学计算器按键及其功能.

2.设置基本运算符对应的元数(实现)

3.当输入”=”后,通过正则表达式,将输入中的运算符和操作数区分开,并将划分好的子串临时储存在向量中.

4.从向量起始位置到末尾,依次判断元素.若该元素为操作数,入操作数栈;若该元素为运算符时,则判断其能否进运算符栈.判断规则如下:

(1)运算符栈底压入”#”.

(2) 若运算符包含”(”,直接进栈

(3) 若运算符不为”)”且不包含”(”,首先判断该运算符是否为”-”.若是,判断该减号位置.若其位于表达式起始处或者向量中减号前一位置元素包含”(”,在操作数栈中压入0.此后判断该运算符与运算符栈顶符号的优先级.若该运算符优先级大于栈顶元素,该运算符入栈;否则栈顶元素出栈并进行对应操作:若为一元运算符,操作数栈出栈一个数,处理后进操作数栈;若为二元运算符,操作数栈出栈两个数,处理后进操作数栈.

(4)若运算符为”)”,运算符栈和操作数栈持续执行(2)中对应操作,直至扫描到一个运算符包含”(”,该运算符再出栈执行(2)对应操作.

(5)扫描到”#”,若表达式正确,则代表算式计算完成,操作数栈栈顶元素即为所求.

5.将操作数栈顶元素出栈,写入输出框,同时将整个算式写入历史记录中.

6. 计算过程中,要对部分可能出现异常进行处理:

(1)括号需匹配

(2)log,ln函数的底数部分需大于0且不等于1,指数部分需大于0

(3)偶次幂根号下数字需大于0

(4)除数不能为0

(5)任何数的0次幂为1

7.字母表达式(运算符)都以”(”结尾,其运算也同括号规律相同.

8.向量实现减号取负方式:

若减号为初始位or减号前一位存在括号

操作数栈压入0

此后减号继续当作二元运算符使用即可

3.4.2多项式计算器:

1. 给出输入示例,避免由于异常输入导致结果异常.

2.输入两个多项式后选择对应运算符,点击”Compute”按键开始计算,对每一个多项式的操作步骤如下:

(1)利用正则表达式将多项式拆分成特定结构的单项式,每个单项式入队列

(2)依次对每个单项式进行以下操作:

<1> 将单项式拆分成系数符号、系数、变量、乘方号、幂次五部分(每一部分都允许缺失).

<2>拆分后对单项式进一步识别,获取其幂次和系数.

<3>以单项式的幂次为键(以下简称key),系数为值(以下简称value),构建键值对,并加入一个哈希表.

3.根据两个多项式的哈希表进行运算的过程如下:

判断运算符:

若运算符为”+”,获取表2中所有keys,并在表1中依次检索:

若表1中存在相同key,更新表1中该key对应的value值为当前值加表2中该key对应的value值.

若表1中不存在相同key,则在表1中添加表2中的<key,value>键值对.

若运算符为”-”,获取表2中所有key,并在表1中检索:

若表1中存在相同key,更新表1中该key对应的value值为当前值减去表2中该key对应的value值

若表1中不存在相同key,则在表1中添加对应的<key,-value>键值对

若运算符为”*”,新建哈希表3,并执行下述代码所示操作:

4.运算结果输出:

由于qt中哈希表默认按键升序排列,因此升幂输出即是按照表中键值对排列顺序输出,降幂输出即为逆序输出.同时要注意:第一位输出若为正数,不输出”+”号.编写输出规范时(两种输出方式通用),要兼顾所有形式的输出.

5.将算式与两种输出添加到历史记录中.

3.4.3.历史记录

在调用show()函数后出现,界面关闭前若未点击”CLC”,关闭后仍然保存算式记录.

4 详细设计及系统实现

该程序所有界面均在python中完成,并在界面初始化函数中进行了一定美化.

4.1 科学计算器

4.1.1 科学计算器数据结构

# 创建计算器界面
calculator = Tk()
calculator.title("Calculator")

4.1.2 科学计算器界面

1.界面展示

2.按键功能

按键

功能

使用方法

清除

点击该键清除光标前的最后一位输入

+/-

符号切换

点击后输入~(),光标跳转至括号内

加法

点击后输入”+”,二元运算符

减法

点击后输入”-”,二元运算符

乘法

点击后输入”*”,二元运算符

除法

点击后输入”/”,二元运算符

(

左括号

点击后输入”(”,用于混合运算,本身无优先级

)

右括号

点击后输入”)”,用于混合运算,本身无优先级

sin

计算正弦函数

点击后输入sin(),光标跳转至括号内

cos

计算余弦函数

点击后输入cos(),光标跳转至括号内

tan

计算正切函数

点击后输入tan(),光标跳转至括号内

log

计算以10为底的对数

点击后输入log(),光标跳转至括号内

.

输入.

点击后输入”.”

1-9

输入对应数字

点击后输入对应数字

3.界面实现

(1)界面组件:Python的Tkinter库

(2)在设计模式中,将组件调整大小后拖动到相应位置并命名

图4.1.2.5   初始科学计算器界面

4.1.3 科学计算机算法实现

def calculate(expression):
    try:
        result = eval(expression)
        history.append(expression)
        return result
    except:
        return "Invalid expression"

2.界面实现

(1)界面组件:Python的Tkinter库

(2)在设计模式中,将组件调整大小后拖动至合理位置并命名.

(1)设置按钮格式与槽函数.

(2)初始化组合框,添加可挑选符号+,-,*.

(3)更改标题,为历史记录按键添加图标.

(4)调整输入的文本字体大小,并设置右对齐

图4.3.2.1历史记录界面

2.界面实现:

(1)界面组件:Python的Tkinter库

(2)在设计模式中,拖动对应组件至合理位置并命名

(3)更改标题,调整输入记录的文本字体大小,并设置右对齐

6 课程设计总结

6.1实现功能

本计算器实现功能如下:

(1)可实现科学计算器的多数运算.

(2)可在一定程度上对异常算式进行错误处理.

(3)多项式计算器可按幂次无序输入,同时进行多项式的+,-,*运算.

(4)实现了历史记录,可查看历史算式.

6.2有待改进部分

本计算器有待改进部分如下:

(1)未能顾全所有异常输入,部分输入可能导致程序出错

(2)异常多项式没有很好的异常处理方式.

(3)历史记录界面制作相对粗略,可对其输入算式格式进行进一步美化.

(4)部分代码存在冗余.

(5)精度设置同系统计算器存在差异

6.3自我总结

本次课程设计是我上大学来完成的首个难度较高的程序设计.从总体设计到局部实现,从抽象逻辑到代码编程,我对基本的数据结构有了进一步了解,也初步掌握了界面设计的相关技能,认识到了合适的数据结构对算法实现的帮助.在完成负数运算时,需要对每一个减号的前一位进行判断.此时若使用栈或队列临时存储正则表达式匹配后的各个子串,在扫描到减号后是无法获取前一位数据的任何信息的.若使用数组临时储存,数组的大小又是未知的.因此选择使用向量作为临时存储结构是极为方便的.同时,在完成该课程设计过程中,我也对程序员平台CSDN,GitHub等有了初步了解,这对于我今后的学习无疑是有很大帮助的.我会牢记这次课设过程,从中吸取教训,并不断进步.

参考文献

附录:

源代码 : from tkinter import *
# 创建计算器界面
calculator = Tk()
calculator.title("Calculator")
# 创建输入框
input_box = Entry(calculator, width=40, borderwidth=5)
input_box.grid(row=0, column=0, columnspan=6, padx=10, pady=10)
# 定义按钮点击事件
def button_click(number):
    current = input_box.get()
    input_box.delete(0, END)
    input_box.insert(0, current + str(number))
def button_clear():
    input_box.delete(0, END)
def button_equal():
    expression = input_box.get()
    try:
        result = eval(expression)
        input_box.delete(0, END)
        input_box.insert(0, result)
    except:
        input_box.delete(0, END)
        input_box.insert(0, "Error")
def button_backspace():
    current = input_box.get()
    input_box.delete(0, END)
    input_box.insert(0, current[:-1])
# 创建按钮
button_1 = Button(calculator, text="1", padx=20, pady=10, command=lambda: button_click(1))
button_2 = Button(calculator, text="2", padx=20, pady=10, command=lambda: button_click(2))
button_3 = Button(calculator, text="3", padx=20, pady=10, command=lambda: button_click(3))
button_4 = Button(calculator, text="4", padx=20, pady=10, command=lambda: button_click(4))
button_5 = Button(calculator, text="5", padx=20, pady=10, command=lambda: button_click(5))
button_6 = Button(calculator, text="6", padx=20, pady=10, command=lambda: button_click(6))
button_7 = Button(calculator, text="7", padx=20, pady=10, command=lambda: button_click(7))
button_8 = Button(calculator, text="8", padx=20, pady=10, command=lambda: button_click(8))
button_9 = Button(calculator, text="9", padx=20, pady=10, command=lambda: button_click(9))
button_0 = Button(calculator, text="0", padx=20, pady=10, command=lambda: button_click(0))
button_add = Button(calculator, text="+", padx=19, pady=10, command=lambda: button_click("+"))
button_subtract = Button(calculator, text="-", padx=20, pady=10, command=lambda: button_click("-"))
button_multiply = Button(calculator, text="*", padx=20, pady=10, command=lambda: button_click("*"))
button_divide = Button(calculator, text="/", padx=20, pady=10, command=lambda: button_click("/"))
button_decimal = Button(calculator, text=".", padx=22, pady=10, command=lambda: button_click("."))
button_open_bracket = Button(calculator, text="(", padx=20, pady=10, command=lambda: button_click("("))
button_close_bracket = Button(calculator, text=")", padx=20, pady=10, command=lambda: button_click(")"))
button_exponent = Button(calculator, text="^", padx=18, pady=10, command=lambda: button_click("**"))
button_sin = Button(calculator, text="sin", padx=14, pady=10, command=lambda: button_click("sin("))
button_cos = Button(calculator, text="cos", padx=14, pady=10, command=lambda: button_click("cos("))
button_tan = Button(calculator, text="tan", padx=14, pady=10, command=lambda: button_click("tan("))
button_log = Button(calculator, text="log", padx=14, pady=10, command=lambda: button_click("log("))
button_sqrt = Button(calculator, text="sqrt", padx=10, pady=10, command=lambda: button_click("sqrt("))
button_power = Button(calculator, text="x^2", padx=12, pady=10, command=lambda: button_click("**2"))
button_equal = Button(calculator, text="=", padx=19, pady=10, command=button_equal)
button_clear = Button(calculator, text="C", padx=19, pady=10, command=button_clear)
button_backspace = Button(calculator, text="⌫", padx=14, pady=10, command=button_backspace)
# 将按钮放置在界面上
button_7.grid(row=1, column=0)
button_8.grid(row=1, column=1)
button_9.grid(row=1, column=2)
button_divide.grid(row=1, column=3)
button_clear.grid(row=1, column=4)
button_backspace.grid(row=1, column=5)
button_4.grid(row=2, column=0)
button_5.grid(row=2, column=1)
button_6.grid(row=2, column=2)
button_multiply.grid(row=2, column=3)
button_open_bracket.grid(row=2, column=4)
button_close_bracket.grid(row=2, column=5)
button_1.grid(row=3, column=0)
button_2.grid(row=3, column=1)
button_3.grid(row=3, column=2)
button_subtract.grid(row=3, column=3)
button_exponent.grid(row=3, column=4)
button_power.grid(row=3, column=5)
button_0.grid(row=4, column=0)
button_decimal.grid(row=4, column=1)
button_equal.grid(row=4, column=2)
button_add.grid(row=4, column=3)
button_sin.grid(row=4, column=4)
button_cos.grid(row=4, column=5)
button_tan.grid(row=5, column=0)
button_log.grid(row=5, column=1)
button_sqrt.grid(row=5, column=2)
# 创建一个空列表用于保存历史运算表达式
history = []
# 定义计算函数
def calculate(expression):
    try:
        result = eval(expression)
        history.append(expression)
        return result
    except:
        return "Invalid expression"
# 调用计算函数并保存历史运算表达式
result = calculate("2 + 3")
print(result)  # 输出:5
print(history)  # 输出:['2 + 3']
result = calculate("4 * 5")
print(result)  # 输出:20
print(history)  # 输出:['2 + 3', '4 * 5']
class Polynomial:
    def __init__(self, coefficients):
        self.coefficients = coefficients
    def add(self, other):
        result = []
        for i in range(max(len(self.coefficients), len(other.coefficients))):
            coeff1 = self.coefficients[i] if i < len(self.coefficients) else 0
            coeff2 = other.coefficients[i] if i < len(other.coefficients) else 0
            result.append(coeff1 + coeff2)
        return Polynomial(result)
    def multiply(self, other):
        result = [0] * (len(self.coefficients) + len(other.coefficients) - 1)
        for i, coeff1 in enumerate(self.coefficients):
            for j, coeff2 in enumerate(other.coefficients):
                result[i + j] += coeff1 * coeff2
        return Polynomial(result)
    def evaluate(self, x):
        result = 0
        for i, coeff in enumerate(self.coefficients):
            result += coeff * (x ** i)
        return result
    class Polynomial:
        def __init__(self, coefficients):
            self.coefficients = coefficients
        def add(self, other):
            result = []
            for i in range(max(len(self.coefficients), len(other.coefficients))):
                coeff1 = self.coefficients[i] if i < len(self.coefficients) else 0
                coeff2 = other.coefficients[i] if i < len(other.coefficients) else 0
                result.append(coeff1 + coeff2)
            return Polynomial(result)
        def multiply(self, other):
            result = [0] * (len(self.coefficients) + len(other.coefficients) - 1)
            for i, coeff1 in enumerate(self.coefficients):
                for j, coeff2 in enumerate(other.coefficients):
                    result[i + j] += coeff1 * coeff2
            return Polynomial(result)
        def evaluate(self, x):
            result = 0
            for i, coeff in enumerate(self.coefficients):
                result += coeff * (x ** i)
            return result
# 运行计算器
calculator.mainloop()