软件工程 | https://bbs.csdn.net/forums/ssynkqtd-05 |
---|---|
作业要求 | https://bbs.csdn.net/topics/617294583 |
这个作业的目标 | 设计一个图形化界面的计算器 |
其他参考文献 | 用Python写一个计算器-CSDN博客 |
Gitcode项目地址
PSP表格
PSP | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
Planning | 计划 | 30 | 20 |
• Estimate | • 估计这个任务需要多少时间 | 30 | 20 |
Development | 开发 | 730 | 910 |
• Analysis | • 需求分析 (包括学习新技术) | 180 | 240 |
• Design Spec | • 生成设计文档 | 60 | 60 |
• Design Review | • 设计复审 | 30 | 30 |
• Coding Standard | • 代码规范 (为目前的开发制定合适的规范) | 10 | 10 |
• Design | • 具体设计 | 30 | 30 |
• Coding | • 具体编码 | 300 | 420 |
• Code Review | • 代码复审 | 60 | 60 |
• Test | • 测试(自我测试,修改代码,提交修改) | 60 | 90 |
Reporting | 报告 | 110 | 95 |
• Test Repor | • 测试报告 | 60 | 60 |
• Size Measurement | • 计算工作量 | 20 | 15 |
• Postmortem & Process Improvement Plan | • 事后总结, 并提出过程改进计划 | 30 | 20 |
合计 | 870 | 1025 |
解题思路描述
题目要求设计一个计算器,要求实现加、减、乘、除、归零。基本操作附加功能可以添加实现次方、幂、三角函数等操作。在了解了相关知识后,我决定采用python语言实现以上功能。
1.设计GUI界面,采用tkinter库进行相关布局。
2.计算方式采用eval()函数进行实现。
3.单元测试,引入unittest库进行测试代码编写进行实现。
接口设计和实现过程
1.输入接口:采用Button控件进行实现
2.计算接口:采用eval函数计算输入表达式的结果值
3.输出接口:采用Label控件进行将结果值进行输出,异常值输出’error’
关键代码展示
以下是计算器功能模块的代码
# 清零功能
def clear(self):
self.equation.set('')
self.result.set('0')
# 回退功能
def back(self):
temp_equ = self.equation.get()
self.equation.set(temp_equ[:-1])
# 计算功能
def calculate(self):
temp_equ = self.equation.get()
temp_result = self.result.get()
try:
result = round(eval(temp_equ), 8)
temp_result = str(result)
except:
temp_result = 'error'
self.result.set(temp_result)
# 计算器输入
def addchar(self, txt):
temp_equ = self.equation.get()
temp_equ = temp_equ+txt
self.equation.set(temp_equ)
# 各类函数输入
def f(self, txt):
func_name = ['sin', 'cos', 'tan', '√x', 'x^y', 'x!', 'lg', 'π']
func_name0 = ['sin(', 'cos(', 'tan(', 'sqrt(', '**', 'factorial(', 'log10(', 'pi']
i = 0
for i in range(8):
if func_name[i] == txt:
break
temp_equ = self.equation.get()
temp_equ = temp_equ+func_name0[i]
self.equation.set(temp_equ)
性能改进
- 使用eval()函数进行浮点数运算的时候会出现精度缺失的问题,采用round()函数进行四舍五入.
单元测试
根据单元测试的三个步骤
(1) 设置数据
(2) 使用被测试函数的功能
(3) 比较实际结果和预期结果
编写了如下代码
import unittest
import tkinter as tk
from Calculator import Calculator
class TestCalculator(unittest.TestCase):
def setUp(self):
self.window = tk.Tk()
self.cal = Calculator(self.window)
def tearDown(self):
self.window.destroy()
# 测试清除功能
def test_clear(self):
self.cal.addchar('5')
self.cal.clear()
result = self.cal.result.get()
self.assertEqual(result, '0')
# 测试回退功能
def test_back(self):
self.cal.addchar('1')
self.cal.addchar('2')
self.cal.addchar('3')
self.cal.back()
result = self.cal.equation.get()
self.assertEqual(result, '12')
# 测试简易计算机的功能
def test_simple_calculator(self):
test_equation = '((9+8)%6-1)*3/2'
for i in test_equation:
self.cal.addchar(i)
self.cal.calculate()
result = self.cal.result.get()
self.assertEqual(result, '6.0')
# 测试三角函数功能
def test_f(self):
fn = ['sin', 'cos', 'tan']
for txt in fn:
self.cal.f(txt)
self.cal.f('π')
self.cal.addchar(')')
if txt != 'tan':
self.cal.addchar('+')
self.cal.calculate()
result = self.cal.result.get()
self.assertEqual(result, '-1.0')
def test_factorial(self):
self.cal.f('x!')
self.cal.addchar('3')
self.cal.addchar(')')
self.cal.calculate()
result = self.cal.result.get()
self.assertEqual(result, '6')
def test_pow(self):
self.cal.addchar('3')
self.cal.f('x^y')
self.cal.addchar('3')
self.cal.calculate()
result = self.cal.result.get()
self.assertEqual(result, '27')
def test_sqrt(self):
self.cal.f('√x')
self.cal.addchar('16')
self.cal.addchar(')')
self.cal.calculate()
result = self.cal.result.get()
self.assertEqual(result, '4.0')
def test_lg(self):
self.cal.f('lg')
self.cal.addchar('1')
self.cal.addchar('0')
self.cal.addchar(')')
self.cal.calculate()
result = self.cal.result.get()
self.assertEqual(result, '1.0')
def test_error(self):
self.cal.addchar('1')
self.cal.addchar('/')
self.cal.addchar('0')
self.cal.calculate()
result = self.cal.result.get()
self.assertEqual(result, 'error')
if __name__ == '__main__':
unittest.main()
异常处理
使用python自带的try语句,在出现异常时输出error
try:
result = round(eval(temp_equ), 8)
temp_result = str(result)
except:
temp_result = 'error'
心得体会
在本次作业中,首次使用了tkinter库进行GUI设计.知道了如何使用tkinter中各个控件的功能.了解到了一个开发一个计算器的基本流程.知道了如何使用单元测试对所使用的代码进行测试.