作业链接
源码的GitHub地址
科学计算器界面及其演示
PSP | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 20 | 10 |
•Estimate | • 估计这个任务需要多少时间 | 20 | 30 |
Development | 开发 | 70 | 70 |
• Design Spec | • 生成设计文档 | 90 | 80 |
• Design Review | • 设计复审 | 30 | 50 |
• Coding Standard | • 代码规范 (为目前的开发制定合适的规范) | 20 | 30 |
• Design | • 具体设计 | 60 | 70 |
• Coding | • 具体编码 | 180 | 220 |
• Code Review | • 代码复审 | 60 | 30 |
• Test | • 测试(自我测试,修改代码,提交修改) | 100 | 100 |
Reporting | 报告 | 80 | 100 |
• Test Repor | • 测试报告 | 20 | 20 |
• Size Measurement | • 计算工作量 | 10 | 10 |
• Postmortem & Process Improvement Plan | • 事后总结, 并提出过程改进计划 | 30 | 30 |
合计 | 820 | 850 |
选择Python作为开发语言,因为它在图形用户界面(GUI)开发方面有强大的库和框架支持,其中包括Tkinter、PyQt、wxPython等。Python也具有广泛的社区支持和丰富的文档资源,使得开发过程更加顺畅。
使用Python的Tkinter库可以创建直观且易于设计的图形用户界面。Tkinter提供了各种UI元素,如按钮、标签、文本框等,使得设计用户友好的UI变得容易,还可以利用Tkinter的布局管理器,例如grid、pack和place,来实现不同屏幕尺寸的适配和界面布局的灵活性。
Python是一门通用编程语言,可以轻松处理计算器的核心功能,包括接收用户输入、执行计算、显示结果等。
使用Python来实现基本的四则运算以及科学计算功能,如开方、取余、幂运算等,非常方便。
Python的字符串处理功能强大,可以轻松处理用户输入的表达式,进行计算,并生成结果。
可以使用Python的打包工具,如PyInstaller、cx_Freeze等,将Python脚本打包成独立的可执行文件(exe)。
这样,用户可以在没有安装Python解释器的情况下运行计算器,提供了更好的可移植性和用户体验。
综上所述,使用Python来实现图形化界面的简易计算器具有易用性、广泛的库支持、丰富的文档资源和跨平台能力等优势,使得它成为一个合适的选择。与前端技术不同,Python的Tkinter库可以在本地运行,无需依赖浏览器,并且更适合创建传统的桌面应用程序。因此我选择python来实现可视化的简易计算器。
每次用户点击"back"按钮时,它会删除当前表达式中的最后一个字符,从而实现了一个逐步删除输入的功能。这在用户输入错误或者想要更改表达式时非常有用。例如,如果用户误输入了一个字符,可以通过点击"back"按钮来修复它,而不必清空整个表达式重新输入
def back(self):
temp_equ = self.equation.get()
self.equation.set(temp_equ[:-1]) # 删除最后一个字符
根据用户的输入构建和更新计算表达式,同时处理一些语法规则和特殊函数的情况,以确保用户可以正确输入和编辑表达式
def getNum(self, arg):
temp_equ = self.equation.get()
temp_result = self.result.get()
# 判断基本语法错误
if temp_result != ' ': # 如果计算器之前没有结果,结果区域应该设置为空。
self.result.set(' ')
if temp_equ == '0' and (arg not in ['.', '+', '-', '*', '÷']): # 如果首次输入为0,则后面不能是数字,只能是小数点或运算符
temp_equ = ''
if len(temp_equ) > 2 and temp_equ[-1] == '0': # 运算符后面也不能出现0+数字的情况,如03,09,x
if (temp_equ[-2] in ['+', '-', '*', '÷', '^']) and (
arg in ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '(', 'π', 'e']):
temp_equ = temp_equ[:-1]
if arg in ['sin', 'cos', 'tan', 'sqrt', 'log']:
temp_equ += arg + '('
temp_equ += arg
self.equation.set(temp_equ)
清除计算器界面上的表达式和结果,将它们恢复到初始状态,便于用户可以开始新的计算或输入新的表达式
def clear(self):
self.equation.set('0')
self.result.set(' ')
用户在计算器界面上点击π或e按钮时,计算器将相应的数值插入到当前表达式中,以便用户可以继续构建表达式
def insert_constant(self, constant):
if constant == 'π':
constant_value = str(math.pi)
elif constant == 'e':
constant_value = str(math.e)
else:
constant_value = ''
temp_equ = self.equation.get()
if temp_equ == '0':
temp_equ = ''
temp_equ += constant
self.equation.set(temp_equ)
在用户点击计算器界面上的特殊函数按钮(如sin、cos、tan等)时,将相应的函数名插入到当前表达式中,以便用户可以继续构建表达式并在函数名后输入相应的参数
def insert_function(self, func):
temp_equ = self.equation.get()
if temp_equ == '0':
temp_equ = ''
temp_equ += func
self.equation.set(temp_equ)
def run(self):
temp_equ = self.equation.get()
temp_equ = temp_equ.replace('÷', '/') # 将÷替换为/
temp_equ = temp_equ.replace('^', '**')
temp_equ = temp_equ.replace('π', str(math.pi)) # 将π替换为math.pi
temp_equ = temp_equ.replace('e', str(math.e)) # 将e替换为math.e
if temp_equ[0] in ['+', '-', '*', '÷', '^']:
temp_equ = '0' + temp_equ
1.导入必要的模块和库:
Tkinter库的各个模块
math库,用于处理数学运算和常数。
2.创建Calculator类:
通过定义一个名为Calculator的类,实现了计算器的功能和界面。
3.初始化主窗口:
在Calculator类的__init__方法中,创建了一个主窗口,并设置了窗口的标题、大小和不可调整大小。
4.创建样式:
使用ttk.Style()来创建窗口控件的样式,调整了按钮的外观和字体。
5.创建显示结果的文本框:
使用StringVar创建了两个文本变量,一个用于显示计算结果(self.result),另一个用于显示当前输入的表达式(self.equation)。
创建了两个Label控件来显示这两个文本变量,并设置它们的样式和对齐方式。
6.定义按钮和按钮样式:
创建了一个包含按钮文本、回调函数和样式的列表button_texts,其中包括数字按钮、运算符按钮和控制按钮。
使用循环将按钮按照指定的样式和回调函数放置到主窗口中。
7.设置网格权重:
使用循环为主窗口的行和列配置了权重,以便在调整窗口大小时,按钮可以根据窗口大小均匀分布。
8.放置结果显示文本框:
使用grid方法将结果显示文本框放置在主窗口的指定位置。
9.定义按钮回调函数:
在Calculator类中定义了一系列的按钮回调函数,包括数字按钮、运算符按钮、清除按钮、特殊函数按钮和计算按钮的回调函数。
这些函数用于处理用户的输入和执行计算。
10.运行主循环:
在if name == “main”:语句下,创建了Tkinter的根窗口,并实例化Calculator类,通过调用root.mainloop()来启动主循环,使计算器界面可以与用户进行交互。
总的来说,通过Tkinter库创建了一个简单的科学计算器界面,用户可以通过点击按钮输入数学表达式,然后计算结果会显示在界面上。各种按钮的回调函数处理了用户输入的不同情况,包括数字、运算符、特殊函数等,然后执行相应的计算。计算结果会显示在界面上的文本框中。
错误处理:程序通过try…except块捕获可能的异常,如除零错误、语法错误和值错误。这提高了程序的健壮性,使其能够更好地处理用户输入错误或不合法的情况。
函数替换:程序在计算之前会检查表达式中是否包含特殊函数(如sin、cos、tan)等。如果有特殊函数,它会将这些函数替换为Python math模块中的对应函数,然后再计算表达式。这确保了特殊函数的正确计算。
常数替换:程序将用户输入的π和e替换为math.pi和math.e,以确保正确计算这些常数。
结果显示:程序使用%.4f格式化浮点数结果,保留四位小数,以提高结果的可读性。
按钮布局:按钮在GUI中的布局经过仔细设计,以确保它们在不同窗口大小下均匀分布,并且易于使用。
对计算器的部分运算和特殊函数进行测试
测试代码:
import unittest
from tkinter import Tk
from spq import Calculator
class TestCalculator(unittest.TestCase):
def setUp(self):
self.root = Tk()
self.calculator = Calculator(self.root)
def tearDown(self):
self.root.destroy()
def test_addition(self):
# 测试加法运算
self.calculator.getNum('2')
self.calculator.getNum('+')
self.calculator.getNum('3')
self.calculator.run()
self.assertEqual(self.calculator.result.get(), '5.0000')
def test_subtraction(self):
# 测试减法运算
self.calculator.getNum('5')
self.calculator.getNum('-')
self.calculator.getNum('3')
self.calculator.run()
self.assertEqual(self.calculator.result.get(), '2.0000')
def test_multiplication(self):
# 测试乘法运算
self.calculator.getNum('4')
self.calculator.getNum('*')
self.calculator.getNum('5')
self.calculator.run()
self.assertEqual(self.calculator.result.get(), '20.0000')
def test_division(self):
# 测试除法运算
self.calculator.getNum('10')
self.calculator.getNum('÷')
self.calculator.getNum('2')
self.calculator.run()
self.assertEqual(self.calculator.result.get(), '5.0000')
def test_power(self):
# 测试幂运算
self.calculator.getNum('2')
self.calculator.getNum('^')
self.calculator.getNum('3')
self.calculator.run()
self.assertEqual(self.calculator.result.get(), '8.0000')
def test_logarithm(self):
# 测试对数函数
self.calculator.insert_function('log(')
self.calculator.getNum('10')
self.calculator.getNum(')')
self.calculator.run()
result_value = self.calculator.result.get()
# 检查是否存在错误
if result_value != 'Error':
self.assertAlmostEqual(float(result_value), 2.3026, delta=0.001)
else:
self.assertEqual(result_value, 'Error')
def test_square_root(self):
# 测试平方根函数
self.calculator.insert_function('sqrt(')
self.calculator.getNum('25')
self.calculator.getNum(')')
self.calculator.run()
result_value = self.calculator.result.get()
# 检查是否存在错误
if result_value != 'Error':
self.assertEqual(result_value, '5.0000')
else:
self.assertEqual(result_value, 'Error')
def test_error_divide_by_zero(self):
# 测试除以零的错误
self.calculator.getNum('5')
self.calculator.getNum('÷')
self.calculator.getNum('0')
self.calculator.run()
self.assertEqual(self.calculator.result.get(), 'Error')
def test_special_functions(self):
# 测试特殊函数
self.calculator.insert_function('sin(')
self.calculator.getNum('1')
self.calculator.getNum(')')
self.calculator.run()
result_value = self.calculator.result.get()
# 检查是否存在错误
self.assertEqual(result_value, 'Error')
def test_clear(self):
# 测试清除功能
self.calculator.getNum('7')
self.calculator.clear()
self.assertEqual(self.calculator.equation.get(), '0')
self.assertEqual(self.calculator.result.get(), ' ')
if __name__ == '__main__':
unittest.main()
如果用户输入的表达式包含除零错误(ZeroDivisionError)、语法错误(SyntaxError)或值错误(ValueError),它会在结果文本框中显示"Error"。
如果没有出现以上异常,会尝试计算表达式:
使用eval()函数来计算表达式的值,并将结果格式化为四位小数。
如果计算成功,将结果显示在计算器的结果文本框中。
如果计算失败(例如,表达式不合法或包含不支持的操作),在结果文本框中显示"Error"。
except (ZeroDivisionError, SyntaxError, ValueError):
self.result.set(str('Error'))
else:
try:
answer = '%.4f' % eval(temp_equ)
self.result.set(str(answer))
except (ZeroDivisionError, SyntaxError, ValueError):
self.result.set(str('Error'))
在实现可视化的科学计算器的过程中,我遇到了许多的挑战,但也积累了许多经验和收获。
选择工具和技术:我考虑了多种语言,包括Java Swing、Python Tkinter以及前端技术(HTML、CSS、JavaScript)。最终,我选择了Python Tkinter,因为它在Python中集成,易于上手,而且python是相较于前端技术和Java我比较熟悉的语言,尽管前端技术能够实现更加优美的界面,但是我对这项技术不够熟悉最终放弃了这个选项。
界面设计:设计一个直观且美观的用户界面是并不是容易的,代码不仅能够实现一些特定的功能,还要界面足够的美观去吸引用户使用,我参考了一些现有的计算器界面,学到了如何使用颜色、字体和布局来创建吸引人的界面。
错误处理和异常处理:在开发这个计算器时,我认识到错误处理和异常处理的重要性。用户可以输入各种不同的表达式,可能导致各种异常情况。因此,我学会了使用try…except块来捕获这些异常,并提供友好的错误消息,以确保程序的健壮性。
数学函数和常数的处理:支持特殊函数(如sin、cos、tan)以及数学常数(π和e)是这个计算器的关键功能之一。我学习了如何在用户输入中识别这些函数和常数,以及如何将它们转换为可计算的形式。这个过程加深了我对Python中数学模块的了解。
布局和窗口自适应:我花了一些时间来设计按钮的布局,以确保它们能够在不同窗口大小下均匀分布。这个经验使我更熟悉了Tkinter中的网格布局和权重分配。
可维护性和扩展性:在开发过程中,我努力保持代码的可维护性和扩展性。我将代码模块化,确保每个函数和方法都有清晰的责任,这使得在将来添加新功能或修复错误时更加容易。