课后作业2

 

1.远程仓库的码云项目地址:https://gitee.com/zhaobing99/personal_project41678

 

2.PSP表格:

PSP2.1

Personal Software Process Stages

预估耗时(分钟)

实际耗时(分钟)

Planning

计划

60*24*6天

60*24*6天

  • Estimate
  • 估计这个任务需要多少时间

60*24*6天

60*24*6天

Development

开发

60*24*6天

60*24*6天

  • Analiysis
  • 需求分析(包括学习新技术)

60*24*2天

60*24*2天

  • Design Spec
  • 生成设计文档

0

0

  • Design Review
  • 设计复审

0

0

  • Coding Standard
  • 代码规范(为目前的开发制定合适的规范)

5分钟

10分钟

  • Design
  • 具体设计

10分钟

20分钟

  • Coding
  • 具体编码

60*24*4天

60*24*4天

  • Code Review
  • 代码复审

60*6时

60*6时

  • Test
  • 测试(自我测试,修改代码,提交修改)

60*6时

60*6时

Reporting

报告

0

0

  • Test Repor
  • 测试报告

0

0

  • Size Measurement
  • 计算工作量

0

0

  • Postmortem & Process Improvement Plan
  • 事后总结,并提出过程改进计划

60分钟

60分钟

 

合计

60*24*6天

60*24*6天

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

3.解题思路描述。即刚开始拿到题目后,如何思考,如何找资料的过程。

答:解题思路描述:刚开始拿到题目后,首先想到的问题是Python如何获得控制台输入的运算表达式。然后是如何判断输入是否包含非法字符,比如:英文,空格,!,@,#,¥,%,&,?等这些非运算字符。接下来想如何实现eval()函数功能。经过查找资料,发现实现这个函数功能有两种方法:一是正则表达式匹配,二是使用逆波兰算法。第一种方法判断优先级不是很好判断,所以选择了第二种方法来完成这次作业。最后就是查找逆波兰表达式的如何实现的原理。

 

4.设计实现过程。设计包括代码如何组织,比如会有几个类,几个函数,他们之间关系如何,关键函数是否需要画出流程图?单元测试是怎么设计的?

答:把设计实现过程分为三个模块。第一模块是获取用户控制台输入,第二个模块是对输入表达式的异常处理,第三个模块是使用逆波兰表达式求解四则运算式。

有main.py和lib.py两个文件,共5个函数,分别为list_to_str:取消空格输入。

illegal_char:正则匹配是否包含非法字符。

get_nibolan:获得逆波兰表达式。

Operation:进行运算。

calculate:传入转换后的逆波兰判断优先级,进行运算。

单元测试有两个,第一个是捕获异常,第二个是生成逆波兰表达式。捕获异常类型有:英文,!,@,#,¥,%,&,?等这些非运算字符。当用户输入这些字符时,

  • 用户输入异常捕获测试过程如下图:

输入:!、a-z、@、#

理论输出:输入包含非法字符,请重新输入

实际输出:输入包含非法字符,请重新输入

  • 逆波兰测试如下图:

输入:3+4*(8-6)

理论输出:[3,4,8,6,'-','*','+']

实际输出:[3,4,8,6,'-','*','+']

 

流程图展示:

 

5.记录在改进程序性能上所花费的时间,描述你改进的思路,并展示一张性能分析图(由VS 2017的性能分析工具自动生成),并展示你程序中消耗最大的函数

 答:所花费的时间如图所示:

 

 

6.代码说明。展示出项目关键代码,并解释思路与注释说明

 答:先展示一下部分代码:

def get_nibolan(source):
    '''
    source = "5*3+4+(2+5*4+(3*2))"
    # [5,3,*,4,+,2,5,4,*,+,2,3,*,+,+]
    '''
    nibolan = []
    st = []  # 一个栈
    for ch in source:  # 遍历整个表达式的每个字符
        if ch == '(':
            st.append(ch)
        elif ch in digits:
            nibolan.append(int(ch))
        elif not st and ch in priority.keys():
            st.append(ch)
        elif st and ch in priority.keys():
            for x in range(st.__len__()):
                z = st[-1]
                p = priority[z]
                if p >= priority[ch]:
                    nibolan.append(st.pop())
                else:
                    break
            st.append(ch)
        elif ch == ')':
            for x in range(st.__len__()):
                if st[-1] == '(':
                    st.pop()
                    break
                else:
                    nibolan.append(st.pop())
    for x in range(st.__len__()):
        nibolan.append(st.pop())
    return nibolan

这是百度百科逆波兰表达式的解释,它的语法规定,表达式必须以逆波兰表达式的方式给出。逆波兰表达式又叫做后缀表达式。这个知识点在数据结构和编译原理这两门课程中都有介绍,下面是一些例子:

正常的表达式 逆波兰表达式

a+b ---> a,b,+

a+(b-c) ---> a,b,c,-,+

a+(b-c)*d ---> a,b,c,-,d,*,+

a+d*(b-c)--->a,d,b,c,-,*,+

a=1+3 ---> a,1,3,+,=

http=(smtp+http+telnet)/1024 写成什么呢?

http,smtp,http,+,telnet,+,1024,/,=

 

下图是我举的一个例子:

3+4*(8-6)

这个式子的逆波兰表达式是 --->3,4,8,6,-,*,+

 

  有两个列表,一个是nibolan列表,存放nibolan表达式,第二个列表是st列表,它用来存放运算符号,用来判断优先级,用户输入表达式,遍历其表达式,当遍历的是数字时,添加到nibolan列表里,当是运算符时,放到st列表进行运算,当遍历到第二个运算符时,判断这个运算符和刚才运算运算符的优先级的高低,如果大于第一个运算符的优先级,那么把这个运算符放到nibolan列表里,如果遍历的是”(“放到st列表进行堆栈,他的优先级最高,接着往下遍历,当遍历到下一个运算符时,将放到st列表堆栈,继续遍历运算符,当遍历的运算符优先级大于上一个运算符优先级时,把该运算符放入nibolan列表,如果小于继续堆栈,直至遍历到”)”;把st列表倒叙放入libolan列表,当在st列表中取到”(”时,不把该符号放入nibolan列表。

 

7.结合在构建之法中学习到的相关内容与个人项目的实践经历,撰写解决项目的心路历程与收获。

 答:就我们这次实验的编程而言,我觉得我学到了很多东西,也提高了我们编程的效率,可以说是事半功倍的。我认为,设计编程的优势主要就在于设计思路。总的来说,自己在编程时犯下的错误,有些尽管很简单,但却难以发现,但是耐下性子总会找到原因的。

 

转载于:https://www.cnblogs.com/zbingbing/p/9913122.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值