软工实践结对第二次作业
作业链接
-
作业博客链接 https://edu.cnblogs.com/campus/fzu/FZUSoftwareEngineering1816W/homework/2160
-
031602323 廖钰萍
-
031602330 苏芳锃
分工
- 廖钰萍:编写爬虫代码,更新WordCount代码
- 苏芳锃:编写博客
PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 15 | 20 |
• Estimate | • 估计这个任务需要多少时间 | 15 | 20 |
Development | 开发 | 915 | 793 |
• Analysis | • 需求分析 (包括学习新技术) | 120 | 92 |
• Design Spec | • 生成设计文档 | 30 | 45 |
• Design Review | • 设计复审 | 30 | 27 |
• Coding Standard | • 代码规范 (为目前的开发制定合适的规范) | 15 | 12 |
• Design | • 具体设计 | 60 | 135 |
• Coding | • 具体编码 | 300 | 382 |
• Code Review | • 代码复审 | 60 | 45 |
• Test | • 测试(自我测试,修改代码,提交修改) | 300 | 55 |
Reporting | 报告 | 90 | 98 |
• Test Repor | • 测试报告 | 60 | 75 |
• Size Measurement | • 计算工作量 | 10 | 8 |
• Postmortem & Process Improvement Plan | • 事后总结, 并提出过程改进计划 | 20 | 15 |
合计 | 1020 | 911 |
解题思路与实现
-
爬虫:利用Python和scrapy框架编写爬虫代码
-
代码组织与内部实现
-
关键部分
- 爬虫部分
def parse_detail (response):
item = CvprItem()
item['Title'] = response.xpath('//div[@id="content"]//dd/div[@id="papertitle"]/text()').extract()
item['Abstract'] = response.xpath('//div[@id="content"]//dd/div[@id="abstract"]/text()').extract()
yield item
def start_requests(self):
url='http://openaccess.thecvf.com/CVPR2018.py'
yield Request(url,headers=self.headers)
def parse(self,response):
links= response.xpath('//div[@id="content"]//dt//a/@href').extract()
for link in links:
link = 'http://openaccess.thecvf.com/'+link
yield Request(link,headers=self.headers,callback=parse_detail)
-
- c++部分
bool Word::isWord()
{
int l = name.length();
if (l < 4) return false;
for (int i = 0;i < 4;i++)
{
if (!(name[i] >= 97 && name[i] <= 122)) return false;
else if (name[i] >= 65 && name[i] <= 90)
name[i] = name[i] + 32; //转小写
}
for (int i = 4;i < l;i++)
{
if (!((name[i] >= 97 && name[i] <= 122) || (name[i] >= 48 && name[i] <= 57)))
return false;
else if(name[i] >= 65 && name[i] <= 90) //转小写
name[i] = name[i] + 32;
}
return true;
}
void Paper::WORDFind(Word W)
{
if (W.isWord())
{
for (vector<Word>::iterator it = WORD.begin();it != WORD.end();it++)
{
if (it->name == W.name)
{
it->count++;
return;
}
}
WORD.push_back(W);
}
}
附加题设计与展示
- 从网站爬取论文标题,发表日期和论文pdf链接,对论文按日期进行分类,生成表格,可通过链接转到pdf页面
- 通过爬取的日期计算每个月份出现的频度,得到论文发表时间的分布图
关键代码解释
def parse_detail (response):
item = CvprItem()
item['Title'] = response.xpath('//div[@id="content"]//dd/div[@id="papertitle"]/text()').extract()
item['Abstract'] = response.xpath('//div[@id="content"]//dd/div[@id="abstract"]/text()').extract()
yield item
def start_requests(self):
url='http://openaccess.thecvf.com/CVPR2018.py'
yield Request(url,headers=self.headers)
def parse(self,response):
links= response.xpath('//div[@id="content"]//dt//a/@href').extract()
for link in links:
link = 'http://openaccess.thecvf.com/'+link
yield Request(link,headers=self.headers,callback=parse_detail)
性能分析与改进
- 改进思路
- 消耗最大函数
单元测试
- 单元测试代码
TEST_METHOD(TestMethod4)
{
// TODO: 在此输入测试代码
string name = "input1.txt";
Assert::AreEqual(wordCount(name), 15);
}
TEST_METHOD(TestMethod5)
{
// TODO: 在此输入测试代码
string name = "input2.txt";
Assert::AreEqual(wordCount(name), 3);
}
TEST_METHOD(TestMethod6)
{
// TODO: 在此输入测试代码
string name = "input3.txt";
Assert::AreEqual(wordCount(name), 44);
}
};
- 测试函数
- 构造测试数据思路
代码签入记录
遇到的问题
- 问题描述
- 最初的wordCount程序数据结构设计不合理,导致后来修改花了许多时间
- 尝试解决
- 百度了很多算法,后来才发现,基本的类没有做好封装,都是用了最基本的数据结构,结果导致实现起来很困难。重新设计了数据结构之后,实现起来更容易一些。
- 收获
- 打算去解决一个问题时,不盲目地动手去做,应该先做好设计,解决起来就不会手忙脚乱
评价队友
- 值得学习的地方
- 布置了任务就会去完成
- 需要改进的地方
- 更积极一些