个人项目作业

个人项目作业

项目 内容
这个作业属于那个课程 班级博客
这个作业的要求在哪里 作业要求
我在这个课程的目标是 学习软件工程相关知识,锻炼软件开发能力。
这个作业在哪个具体方面帮我实现目标 完成个人项目,体会单元测试和PSP流程
作业正文 作业正文

1.About(1')

2.在开始实现程序之前,在下述 PSP 表格记录下你估计将在程序的各个模块的开发上耗费的时间。(0.5' + 0.5')

PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划
·Estimate 估计这个任务需要多少时间 60(7.2%) 40(阅读具体要求,完成了博客框架)
Development 开发
·Analysis 需求分析 (包括学习新技术) 120(14.5%) 90(c++复习,相关插件资料阅读)
·Design Spec 生成设计文档 60(7.2%) 30
·Design Review 设计复审 (和同事审核设计文档) 10(1.2%) 10
·Coding Standard 代码规范 (为目前的开发制定合适的规范) 10(1.2%) 10
·Design 具体设计 60(7.2%) 30
·Coding 具体编码 180(21.6%) 90
·Code Review 代码复审 60(7.2%) 60
·Test 测试(自我测试,修改代码,提交修改) 120(14.5%) 90
Reporting 报告
·Test Report 测试报告 60(7.2%) 30
·Size Measurement 计算工作量 30(3.6%) 20
·Postmortem & Process Improvement Plan 事后总结, 并提出过程改进计划 60(7.2%) 30
合计 830 530

由于对C++的诸多特性没有很好的掌握,预估时对每个部分的时间估计都过于宽松。实际完成时间大致会比预估少1/3-1/2。

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

刚拿到题目时,考虑如何计算两条直线的交点。模拟解方程的过程过于复杂,且不够简便,于是考虑其他方法,搜索资料后发现可以采用计算几何的方法,利用向量求解交点。

参考1:直线交点

参考2:圆交点

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

整体结构如上,开始设计时基本决定分两类,Point(点类,包含点的减法,叉乘与点乘方法)/Line(线类,包含求该对象与另一线对象交点的方法),并决定采取map/queue分别存放交点与已读入的直线。

完成第一版后,为了改进性能对原始设计进行了一些修改,最终的类结构如下所示

class Point
{
public:
	double x;
	double y;
	Point();
	Point(double _x, double _y);
	Point operator -(const Point& b)const;
	double operator *(const Point& b)const;
	double operator ^(const Point& b)const;
	bool operator <(const Point& b)const;
	bool operator ==(const Point& b)const;
};
#pragma once
#include "Point.h"
#include <vector>
#include <set>
#include<iostream>
using namespace std;

class Line
{
public:
	Point s;
	Point e;
	Line();
	Line(Point _s, Point _e);

	void intersect(set<Point>* pointset, const Line& b);
};

由于整体逻辑比较简单,并未对关键函数绘制流程图。

单元测试方面,则是对点类与线类的每个方法分别进行测试,确保在给定数据范围内的正确性。着重测试了求交点的intersect方法,利用随机数生成数据,并利用Geogebra画图求得交点的数值解,进而保证了intersect方法的正确性。

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

性能改进与单元测试编写共150分钟,

通过性能分析工具,对原始代码进行分析,发现原本使用的交点map插入前需要调用find方法判断是否已存在该交点。因此放弃map转而使用set+trycatch块,将消耗时间大量减少。

最终的性能分析图如图所示,其中Intersect方法占用时间最多(90.45%)

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

void Line::intersect(set<Point>* pointset, const Line& b)
{
	Point res = s;
	if (sgn((s - e) ^ (b.s - b.e)) == 0)
	{
		return;
	}
    //判断平行(本应判断是否重合,由于本题不会出现重合情况,故舍去部分代码)
	double t = ((s - b.s) ^ (b.s - b.e)) / ((s - e) ^ (b.s - b.e));
	res.x += (e.x - s.x) * t;
	res.y += (e.y - s.y) * t;
    //计算几何求交点过程
	try {
		pointset->insert(res);
	}catch (exception e){}
    //利用set的不重复特性,添加交点结果至set中
}

关键代码为Line的intersect方法,说明在注释中。

for (int i = 0; i < n; i++) {
		if (cmdin) in >> sub >> x1 >> y1 >> x2 >> y2;
		else cin >> sub >> x1 >> y1 >> x2 >> y2;
		Line tempLine = Line(Point(x1, y1), Point(x2, y2));
		if (i != 0) {
			for (Line b : lineVector) {
				tempLine.intersect(&points,b);
			}
		}
		lineVector.push_back(tempLine);
	}
	if (cmdout)    out << points.size() << endl;
	else cout << points.size() << endl;

外部调用则集成在IntersectLine函数中,如上所示,其主要部分是一个二重循环,对每一个读入的Line,与之前读入并存在lineVector中的Line依次求交点。

7.程序评分规则要求截图

消除 Code Quality Analysis 中的所有警告

单元测试数目:

覆盖率:

查看后添加了一部分单元测试,但没有增长,由于覆盖率与代码正确性无必然关系,因此没有再添加单元测试内容

posted @ 2020-03-08 19:35  PandapanQAQ  阅读(244)  评论(2编辑  收藏  举报