PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 30 | 30 |
· Estimate | · 估计这个任务需要多少时间 | 30 | 30 |
Development | 开发 | 940 | 1420 |
· Analysis | · 需求分析 (包括学习新技术) | 120 | 180 |
· Design Spec | · 生成设计文档 | 30 | 30 |
· Design Review | · 设计复审 | 60 | 180 |
· Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 10 | 10 |
· Design | · 具体设计 | 240 | 240 |
· Coding | · 具体编码 | 360 | 540 |
· Code Review | · 代码复审 | 60 | 60 |
· Test | · 测试(自我测试,修改代码,提交修改) | 60 | 180 |
Reporting | 报告 | 100 | 160 |
· Test Repor | · 测试报告 | 60 | 120 |
· Size Measurement | · 计算工作量 | 10 | 10 |
· Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 30 | 30 |
合计 | 1040 | 1580 |
<dt class="ptitle"><br><a href="content_cvpr_2018/html/Das_Embodied_Question_Answering_CVPR_2018_paper.html">Embodied Question Answering</a></dt>
@href 属性 和 http://openaccess.thecvf.com/ 拼接而成的。
所以就先获取所有论文的主页,然后再依次爬取所有的论文的信息,利用 lxml, bs4, 正则 提取出
相应位置的信息。 一开始是做单进程的,完整爬一遍要9分钟多,就改了一个多进程的版本。
全部爬完之后再输出到文件。
def scrape(lock, data, url):
try:
text = get_page(url)
pdf_links, abstracts, authors, titles, booktitles, months, years = data
# print(text)
html = etree.HTML(text)
pdf_link = html.xpath(‘//a[contains(text(), "pdf")]/@href‘)[0]
pdf_link = ‘http://openaccess.thecvf.com/‘ + pdf_link[6:]
abstract = html.xpath(‘//div[@id="abstract"]/text()‘)[0]
abstract = abstract[1:]
soup = BeautifulSoup(text, ‘lxml‘)
detail = soup.find(class_="bibref")
regex = ‘(\w+) = {([\S\xa0 ]+)}‘
results = re.findall(regex, detail.getText())
author = results[0][1]
title = results[1][1]
booktitle = results[2][1]
month = results[3][1]
year = results[4][1]
lock.acquire()
pdf_links.append(pdf_link)
abstracts.append(abstract)
authors.append(author)
titles.append(title)
booktitles.append(booktitle)
months.append(month)
years.append(year)
lock.release()
except ConnectionError:
print(‘Error Occured ‘, url)
finally:
print(‘URL ‘, url, ‘ Scraped‘)
主要部分就是实现词组统计这一块
private HashMap<String, Integer> countContent(List<String> contents, int m) {
HashMap<String, Integer> map = new HashMap<>();
String splitRegex = "[\\s+\\p{Punct}]+";
String splitStartRegex = "^[\\s+\\p{Punct}]+";
String wordRegex = "^[a-zA-Z]{4,}.*";
Pattern pattern = Pattern.compile(splitRegex);
for (String content : contents) {
String[] temp = content.split(splitRegex);
List<String> splits = new ArrayList<>();
Matcher matcher = pattern.matcher(content);
while (matcher.find()) {
splits.add(matcher.group());
}
boolean isSplitStart = content.matches(splitStartRegex);
for (int i = 0; i < temp.length - m + 1; i++) {
StringBuilder stringBuilder = new StringBuilder();
if (temp[i].matches(wordRegex)) {
stringBuilder.append(temp[i]);
} else {
continue;
}
boolean isContinue = true;
for (int j = 1; j < m; j++) {
if (!temp[i + j].matches(wordRegex)) {
isContinue = false;
break;
} else {
if (isSplitStart) {
stringBuilder.append(splits.get(i + j));
} else {
stringBuilder.append(splits.get(i + j - 1));
}
stringBuilder.append(temp[i + j]);
}
}
if (isContinue) {
String words = stringBuilder.toString().toLowerCase();
if (!map.containsKey(words)) {
map.put(words, 1);
} else {
int num = map.get(words);
map.put(words, num + 1);
}
}
}
}
return map;
}
一开始有想过通过写正则,直接匹配出符合条件的,emmmm....还是有点难处理。
所以先将句子通过分割符分割,分割出每个词。匹配出所有的分割符(词组统计时候,要求带分隔符连接起来)。
然后直接暴力求解...,判断出符合条件的词组。将结果存入map中,并记录出现的次数。
测试时使用爬取CVPR的979篇论文作为输入,命令行参数为-i test.txt -n 15 -m 3 -o output.txt,
使用权重统计词组词频,每三个单词为一个词组,输出词频前15的词组存放到output.txt
循环运行100次,性能分析结果如下
代码覆盖率如下
使用VisualVM进行性能分析发现,Main中统计输入文件词组词频的WordsCount.countContent和统
计输入文件单词总数的WordsCount.getWordsSum占用时间最多,占用了90%左右的时间
在这列出三个单元测试并给出中文注释,所有的单元测试代码可以在github中的test项目中看到。
import org.junit.Test;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static org.junit.Assert.*;
public class CalMostTest {
String path = "input.txt";
HandleContent handleContent = new HandleContent(path);
// -m 词组单词数设为1
// -w 权重设为0
WordsCount wordsCount = new WordsCount(handleContent, 1, 0);
HashMap<String, Integer> map = wordsCount.getMap();
CalMost calMost = new CalMost();
@Test
//无 -n 参数输入时
//单词数超过十个则输出前十个单词及词频
//不足则输出所有单词及词频
public void mostWords() {
List<Map.Entry<String, Integer>> list = calMost.mostWords(map);
list.forEach(System.out::println);
}
@Test
//有 -n 参数输入时
//单词数超过n个则输出前n个单词及词频
//不足则输出所有单词及词频
public void mostWords1() {
List<Map.Entry<String, Integer>> list = calMost.mostWords(map,9);
list.forEach(System.out::println);
}
}
import org.junit.Test;
import java.util.HashMap;
import java.util.Map;
import static org.junit.Assert.*;
public class WordsCountTest {
String path = "input.txt";
HandleContent handleContent = new HandleContent(path);
// -m 词组单词数设为1
// -w 权重设为0
WordsCount wordsCount = new WordsCount(handleContent, 1, 0);
@Test
//获取单词总数
public void getSum() {
System.out.println(wordsCount.getSum());
}
@Test
//获取map内容,单词及其词频数
public void getMap() {
System.out.println(wordsCount.getMap().toString());
}
}
import org.junit.Test;
public class HandleContentTest {
String path = "test.txt";
//声明一个handleContent对输入内容进行分类
//将所有的title和所有的abstract各自分到一起
HandleContent handleContent = new HandleContent(path);
@Test
//输出应为所有的title内容
public void getTitles() {
System.out.println(handleContent.getTitles().toString());
}
@Test
//输出应为所有的abstract内容
public void getAbstracts() {
System.out.println(handleContent.getAbstracts().toString());
}
@Test
//输出应为title + abstract 内容
public void getHandledContent() {
System.out.println(handleContent.getHandledContent());
}
}
对于题意的理解存在问题,题目要求标点符号也要算成分隔符,例如question(“orange就可以
分割成question和orange两个单词。但是我们对连字符"-"产生了误解,认为像Super-Resolution
这样的从语义上来看,只能算一个单词,所以产生了错误。经过和助教还有其他同学的沟通后,才明
白了自己的错误。
for (int j = 1; j < m; j++) {
if (!temp[i + j].matches(wordRegex)) {
isContinue = false;
break;
} else {
if (isSplitStart) {
stringBuilder.append(splits.get(i + j));
} else {
stringBuilder.append(splits.get(i + j - 1));
}
stringBuilder.append(temp[i + j]);
}
}
志炜大佬精通Java、Python,项目经验丰富,号称数计最强的男人,本次的结对作业让我实实在在地体会到了这位巨佬的惊人实力。这次的结对作业对于他来说并没有什么难度,但是像我这种刚学Java的人就不一样了。但是每次在我遇到问题时,他都能够一眼看出我的问题出在哪里,告诉我遇到这种问题该如何解决并提出一些新的思路。而且志炜大佬总是会非常严格认真地纠正我的代码习惯(我之前对这个并不在意)。在他的帮助下,我对Java的学习和理解又得到了更进一步的加深。和志炜大佬一起合作完成本次作业,让我的Java学习之旅轻松又愉快。为了感谢志炜大佬一段时间的帮助,我决定送一套自己的亲笔签名照给他,希望他能够喜欢(必须喜欢)~~
第N周 | 新增代码行 | 累计代码行 | 本周学习耗时(小时) | 累计学习耗时(小时) | 重要成长 |
---|---|---|---|---|---|
1 | 200 | 200 | 15 | 15 | 学习Java以及IDEA的使用 |
2 | 10 | 25 | 阅读构建之法,了解了NABCD模型,学会了原型工具的使用 | ||
3 | 600 | 800 | 20 | 45 | 阅读《第一行代码》学习Android开发,Java进一步学习 |
原文:https://www.cnblogs.com/yaozhengyi/p/9769349.html