课后作业2 - 个人项目

Deadline(截止时间): 2018-09-19 23:00pm

零、任务背景

很多同学在第一次作业中都说将来希望从事计算机行业,对计算机感兴趣,同时觉得自己的专业能力不够,尤其是程序设计能力。而软件工程能力的锻炼需要以程序设计能力作为基础,所以此次作业给大家提供一个机会锻炼自己的程序设计能力。

《构建之法》第一章第一节移山公司程序员阿超为了完成老师交代的任务写了一个软件,可以自动出题并计算题目的结果。此次作业我们希望大家构建出这个软件的一个核心模块,自动计算题目结果。一个计算题我们将其称为表达式,程序自动计算题目结果,我们称为求表达式的值。

一、任务描述

实现一个能够对表达式进行求值的控制台程序。程序至少能支持简单的加减乘除运算以及简单的混合四则运算, 如下所示:

3 + 4 = ?
3 - 4 = ?
3 * 4 = ?
3 / 4 = ?
3 + 5 / 2 = ?

若能力与时间足够可以考虑让程序可以支持括号,分数运算等。

注释:

  • 控制台程序:可以通过命令行运行该程序并向该程序传递参数。

二、编码要求

  1. 按照[附录1]提示,Fork 码云 项目 到自己的仓库,在码云仓库中新建一个学号为名的文件夹,完成项目后正确发起一个Pull Request,并确保自己的代码最终成功签入(成功签入将在源仓库中看到自己学号为名的文件夹)。
  2. 在开始实现程序之前,在PSP表格[附录2]记录下你估计在程序开发各个步骤上耗费的时间,在你实现程序之后,在PSP表格记录下你在程序的各个模块上实际花费的时间。
  3. 使用Python、Java或C#语言实现,C#请使用Visual Studio Community 2017进行开发,运行环境为64-bit Windows 10。
  4. 提交的代码要求经过Code Quality Analysis工具的分析并消除所有的警告。
  5. 完成项目的首个版本之后,请使用性能分析工具Studio Profiling Tools来找出代码中的性能瓶颈并进行改进。
  6. 使用码云[附录3]来管理源代码和测试用例,代码有进展即签入码云。签入记录不合理的项目会被助教抽查询问项目细节。
  7. 使用单元测试[附录4]对项目进行测试,并使用插件查看测试分支覆盖率等指标;写出至少10个测试用例确保你的程序能够正确处理各种情况。

三、博客撰写要求

  1. 在文章开头写出自己目前写过的代码量以及自己的码云项目地址。
  2. 给出PSP表格。
  3. 解题思路描述。即刚开始拿到题目后,如何思考,如何找资料的过程。
  4. 设计实现过程。设计包括代码如何组织,比如会有几个类,几个函数,他们之间关系如何,关键函数是否需要画出流程图?单元测试是怎么设计的?
  5. 记录在改进程序性能上所花费的时间,描述你改进的思路,并展示一张性能分析图(由VS 2017的性能分析工具自动生成),并展示你程序中消耗最大的函数。
  6. 代码说明。展示出项目关键代码,并解释思路与注释说明。
  7. 结合在构建之法中学习到的相关内容与个人项目的实践经历,撰写解决项目的心路历程与收获。

四、需求

实现一个命令行程序,不妨称之为calculate。

第一步、实现读取命令行参数功能

输入表达式以命令行参数传入程序。例如我们在命令行窗口(cmd)中输入:

//C语言类
calculate.exe 3+5

//Java语言
java Calculate 3+5

//Python语言
python calculate.py 3+5

此时程序会获取从命令行输入的字符串并将其从命令行窗口显示出来。如下图所示:

各种语言获取命令行参数的方法:

第二步、实现为表达式求值功能

经过第一步,大家已经能够从命令行获取字符串了,接下来就是对获取的字符串进行求值。我们可以从最简单的开始做起:

  • 处理只有两个操作数的加法运算
    重点在于将字符串中的数字字符转变为对应的数字,并将数字相加。

  • 能支持两个操作数的加减乘除运算
    由于要支持新的运算符,所以程序应该能够识别运算符,根据运算符的不同对两个操作数进行不同的运算。

  • 能支持简单混合运算
    大家可能会想到继续使用条件语句来判断运算符是什么,由此来求得字符串的值。如果只有一个运算符,那这个方法还是可行的,但现在表达式中不只一个运算符,比如3个运算符,4个运算符呢,通过增加不同的if/else吗?显然这不是一个好的解决问题的方法,尤其是还需要处理运算符的优先级。实际上已经有一些比较好的数据结构可以高效的表示四则运算,大家可以去搜索逆波兰表达式。另外,对于四则运算表达式的解析也有成熟的算法:调度场算法,详细的介绍可以参见以下几篇文章:

你也可以自己去搜集其他相关材料。

五、测试须知

组织目录

助教在测试时,将运行自动测试程序编译源文件并运行,进行批量测试,因此请保证项目的组织目录符合要求.

Java

对于使用Java语言的项目有以下两点要求:

【以学号为名的文件夹中】的目录下必须有src文件夹
在src目录下必须有名为Main.java文件,且Main.java中包含 public static void main(String[] args) 方法
一个Java项目的示例组织目录如下所示:

031602111 (文件夹名字为学号)
|- src
  |- Main.java(主程序,可以从命令行接收参数)
  |- lib.java(包含其它自定义函数,可以有多个,对名字不做要求)

C#

对于使用C# 语言的项目有以下两点要求:
【以学号为名的文件夹中】的目录下必须有src文件夹,在src文件夹中是可在VS2017下编译运行的解决方案,解决方案的名字必须为 Calculate,一个C#工程示例组织目录如下所示:

031602111 (文件夹名字为学号)
|- src
   |- Calculate.sln
   |- Calculate
       |- stdafx.cs
       |- stdafx.h
       |- Calculate.cs
       |- Calculate.csxproj

Python

对于使用Python语言的项目有以下两点要求:

【以学号为名的文件夹中】的目录下必须有src文件夹
在src目录下必须有名为main.py文件。
一个Python项目的示例组织目录如下所示:

031602111 (文件夹名字为学号)
|- src
  |- main.py(主程序,可以从命令行接收参数)
  |- lib.py(包含其它自定义函数,可以有多个,对名字不做要求)

助教在测试时,将自动按照指定编译环境编译源代码,并利用命令行进行批量测试。

错误处理

本次自动测试会加入各种各样出错情况的测试,要求开发者程序不能崩溃,并且能够尽可能精确报错。你可以有“容错性”的出错设计,但必须输出必要的提示或说明。

六、评分规则

发现雷同作业一律0分,抄袭被发现且屡教不改者将上报计算机系和学校给予处分处理

博客评分规则

  1. 在文章开头写出你目前的代码量。(1')
  2. 在文章开头给出你所Fork的同名仓库的Github项目地址。(1')
  3. 在开始实现程序前,在下述PSP表格记录下你估计将在程序的各个模块的开发上耗费的时间。并说明估计根据。(5')
  4. 程序对表达式类型的支持程度。描述你的程序对不同类型表达式求值的支持程度。(20')
    • 能支持两个操作数,一种运算符。(5')
    • 能支持两个操作数的简单四则运算(只有一个操作符)。(10')
    • 能支持简单混合四则运算(最多有3个操作符,没有括号)。(15')
    • 能支持稍微复杂的混合四则运算(最多3个操作符,有括号)。(20')
  5. 程序设计与实现过程。设计包括代码如何组织,比如会有几个类,几个函数,他们之间关系如何,关键函数是否需要画出流程图?说明你实现算法的关键部分(不必列出源代码),以及实现过程中遇到的关键问题与困难。(20')
    • 代码组织情况。(5')
    • 关键函数流程图。(5')
    • 说明实现算法的关键部分。(5')
    • 实现过程中遇到的问题与困难。(5')
  6. 程序单元测试展示。展示出项目部分单元测试代码,并说明测试的函数,构造测试数据的思路。并将单元测试得到的测试覆盖率截图,发表在博客中。(5')
  7. 程序中的异常处理说明。在博客中详细介绍每种异常的设计目标。每种异常都要选择一个单元测试样例发布在博客中,并指明错误对应的场景。(5')
  8. 在你实现完程序之后,在附录提供的PSP表格记录下你在程序的各个模块上实际花费的时间。(2')

七、附录

1. Fork项目并创建文件夹

  • 打开链接,点击Fork按钮,将仓库 personal_project41612 或者 personal_project41634 拷贝到自己的同名仓库中,如下图所示:

  • 拷贝成功后,可以看到自己已经拥有了一个同名仓库

  • 在对应语言下创建以学号为名的文件夹,确保所有本地的改动都已 push 后,可以在自己的仓库中向源仓库(personal_project41612或personal_project41634)发起Pull Request:

  • 填写标题与说明,点击创建,提交请求,此后只需等待仓库主人通过审核后,你的代码就可以成功合并进源仓库(personal_project41612或personal_project41634)

  • 如在发起 pull request 后代码发生新的变化,可重复发起 pull request ,助教将合并最新的修改到源仓库

2. PSP表格

PSP是卡耐基梅隆大学(CMU)的专家们针对软件工程师所提出的一套模型:Personal Software Process (PSP, 个人开发流程,或称个体软件过程)。

一个功能完备的程序不是一蹴而就的。通过将表达式求值的需求划分为2个部分,可将一个大任务划分为可操作的小任务,同时最好按照任务难度或紧急程度指定各个任务的完成次序。因此,在动手开发之前,要先估计将在程序各模块开发所需耗费的时间,以及完成整个项目所需的时间,将这个[估计值]记录下来,写成PSP 的形式。
PSP的目的是:记录工程师如何实现需求的效率,和我们使用项目管理工具(例如微软的Project Professional,或者禅道等)进行项目进度规划类似。
有关PSP的更多内容,请自行阅读邹欣老师的博客:现代软件工程讲义 2 工程师的能力评估和发展

3. 码云

请阅读博客:源代码管理的新15条建议
本次作业要求使用码云进行源代码管理,代码有进展即签入(可以理解为上传到)码云。签入记录不合理的项目会被助教抽查询问项目细节。
对代码签入的具体要求如下:根据需求划分功能后,每做完一个功能,编译成功后,应至少commit一次。本例中,至少应区分参数处理功能和表达式分析功能,即分别针对参数处理功能、表达式分析功能,编译成功后,总共至少应commit两次。具体的功能划分,请自行定义,并在撰写博客时体现出来,遵循自己对需求的功能划分来提交代码即可。
对Commit不是很熟悉的话,请阅读阮一峰的博客:Commit message 和 Change log 编写指南,了解更多细节

4. 单元测试

请根据自己以往积累的测试经验,在编码完成之后,提交产品之前,设计测试用例,并编写单元测试,对自己的项目进行测试。
首先,至少应采用白盒测试用例设计方法来设计测试用例,其他测试方法不限。其次,要设计至少10个测试用例,确保你的程序能够正确处理各种情况。最后,结合测试评估的要求,对自己的测试设计进行评价,这些测试用例能满足该程序测试的要求吗?
另一个重要的措施是要把单元测试自动化,这样每个人都能很容易地运行它,并且可以使单元测试每天都运行。每个人都可以随时在自己的机器上运行。团队一般是在每日构建中运行单元测试的,这样每个单元测试的错误就能及时被发现并得到修改。
推荐阅读邹欣老师的博客:现代软件工程讲义 2 开发技术 - 单元测试 & 回归测试

posted on 2018-09-12 15:23  白马学软件开发  阅读(484)  评论(1编辑  收藏  举报

导航