项目 | 内容 |
---|---|
这个作业属于哪个课程 | 任课教师博客主页链接 |
这个作业的要求在哪里 | 作业链接地址 |
课程学习目标 | 熟悉软件开发整体流程,提升自身能力 |
本次作业在哪个具体方面帮助我们实现目标 | 第一次体验一个完整的工程 |
任务一:
点评作业博客地址
源代码地址
点评内容:在博客的实验运行截图中,未显示出你所运行的文件是哪个;通过研读代码知,已在代码中定义了要运行的文件名,我认为这样做程序的适用范围就变小了,所以建议应扩大程序的适用性;同时通过阅读你的博客及代码,意识到了自己作业过程中所出现的代码不规范、博客结构不合理等问题,并进行了改正。在你的PSP中“计划共完成需要的时间”与“实际完成需要的时间”两列数据的差异主要在与编码阶段预计时间与实际时间之间的误差,可能更多的是由于基础知识不扎实或粗心造成的误差,希望通过结队编程,能够把这部分做的更好
点评心得:通过阅读以及点评队友的实验二内容,了解了队友的代码风格并且对其实验过程中采用的高效算法以及好的想法进行了探讨以及借鉴,同时,对其在实验过程中出现的错误以及失误等提出了自己的意见及建议等,为继续进行结队项目奠定了基础。
任务二:
a.需求分析
采用两人合作方式,设计开发一个英文文本统计分析软件,使之具有以下功能:
(1)实验2要求的功能;
(2)单词频数可视化柱状图要求是以下样式:
(3)统计该文本行数及字符数;
(4)各种统计功能均提供计时功能,显示程序统计所消耗时间(单位:ms);
(5)可处理任意用户导入的任意英文文本;
(6)人机交互界面要求GUI界面(WEB页面、APP页面都可);
(7)附加分功能:统计文本中除冠词、代词、介词之外的高频词;
(8)附加分功能:统计前10个两个单词组成的词组频率。
b.软件设计:使用类图
c.核心功能代码展示:展示核心功能代码
人机交互界面的实现:
public class main extends JFrame
{
//高频词输出按钮
private static JButton highFrequencyButton;
//统计指定单词个数按钮
private static JButton wordCountButton;
//词频写入文件按钮
private static JButton printFile;
//行数单词数统计按钮
private static JButton lineWordCount;
//版面
private static JLabel input;
//框架
private static JFrame statistics;
//文件名
private static JTextField file2;
private static JLabel file ;
public static FileReader fr;
static BufferedReader br;
//行数
static int rowNumber=0;
//单词数
static int wordNumber=0;
//统计行数单词数所用时间
static long time;
/**初始化登陆界面*/
public main ()
{
//设置字体
Font font =new Font("楷体", Font.PLAIN, 30);
statistics=new JFrame("英文文本统计分析软件");
statistics.setSize(500, 600);
input=new JLabel();
file=new JLabel("输入文件名:");
file.setBounds(20, 40, 100, 50);
highFrequencyButton=new JButton("查看前N个高频词");
highFrequencyButton.setBounds(20, 150, 400, 50);
highFrequencyButton.setFont(font);
wordCountButton=new JButton("统计指定单词词频");
wordCountButton.setBounds(20, 250, 400, 50);
wordCountButton.setFont(font);
printFile=new JButton("写入文件");
printFile.setBounds(20, 450, 400, 50);
printFile.setFont(font);
lineWordCount=new JButton("统计行数单词数");
lineWordCount.setBounds(20, 350, 400, 50);
lineWordCount.setFont(font);
//加入文本框
file2 = new JTextField();
file2.setBounds(150, 40, 250, 40);
input.add(file);
input.add(file2);
input.add(highFrequencyButton);
input.add(wordCountButton);
input.add(printFile);
input.add(lineWordCount);
statistics.add(input);
statistics.setVisible(true);
statistics.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
statistics.setLocation(300,400);
}
柱状图的实现
public void paint(Graphics g)
{
int Width = getWidth();
int Height = getHeight();
int leftMargin = 50;//柱形图左边界
int topMargin = 50;//柱形图上边界
Graphics2D g2 = (Graphics2D) g;
int ruler = Height-topMargin;
int rulerStep = ruler/20;//将当前的高度平分为20个单位
g2.setColor(Color.WHITE);//绘制白色背景
g2.fillRect(0, 0, Width, Height);//绘制矩形图
g2.setColor(Color.LIGHT_GRAY);
for(int i=0;i<rulerStep;i++){
g2.drawString((30000-1500*i)+"个", 8, topMargin+rulerStep*i);//绘制Y轴上的数据
}
g2.setColor(Color.darkGray);
int m=0;
for (Entry<String, Integer> entry : map.entrySet())
{
int value =entry.getValue();
int step = (m+1)*40;//设置每隔柱形图的水平间隔为40
g2.fillRoundRect(leftMargin+step*2,Height-value/50-5, 40, value, 40, 10);//绘制每个柱状条
g2.drawString(entry.getKey(), leftMargin+step*2, Height-value/50-5); //标识每个柱状条
m++;
}
}
查询并显示指定单词词频并统计时间
inputButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
if (event.getSource()==inputButton)
{
long start = System.currentTimeMillis();
String word=word2.getText();
if (!word.isEmpty())
{
Map<String,Integer> map = new TreeMap<String, Integer>();
String[] input= word.split(" ");
int i;
String print = "";
for (i=0; i<input.length; i++)
{
for (Entry<String, Integer> entry : maps.entrySet())
{
if (input[i].equals(entry.getKey()))
{
map.put(entry.getKey(), entry.getValue());
print += entry.getKey() + ":" + entry.getValue()+" ";
break;
}
}
}
long time=System.currentTimeMillis() - start;
JOptionPane.showConfirmDialog(null,print+"
"+"所用时间:"+(System.currentTimeMillis() - start)+"ms","结果",JOptionPane.DEFAULT_OPTION);
plot histogram=new plot(map,input.length);
histogram.setVisible(true);
}
else
{
JOptionPane.showConfirmDialog(null, "请输入要查询的信息!","提示",JOptionPane.DEFAULT_OPTION);
}
}
}
});
输出到文件
Map<String,Integer> Map = new LinkedHashMap<String, Integer>();
/**按字典顺序排序*/
void Sort(Map<String, Integer> map)
{
Set<Entry<String,Integer>> m= map.entrySet();
LinkedList<Entry<String, Integer>> List = new LinkedList<Entry<String,Integer>>(m);
Collections.sort(List, new Comparator<Entry<String,Integer>>()
{
public int compare(Entry<String, Integer> a, Entry<String, Integer> b)
{
return a.getKey().compareTo(b.getKey());
}
});
for (Entry<String,Integer> entry: List)
{
Map.put(entry.getKey(), entry.getValue());
}
}
/**写入文件*/
void PrintToF(Map<String, Integer> map)throws IOException
{
long start = System.currentTimeMillis();
Sort(map);
File file = new File("result.txt");
FileWriter f = new FileWriter(file.getAbsoluteFile());
for (Entry<String,Integer> w: Map.entrySet())
{
f.write(w.getKey() + "/" + w.getValue()+" ");
}
f.close();
JOptionPane.showConfirmDialog(null,"所用时间:"+(System.currentTimeMillis() - start)+"ms","结果",JOptionPane.DEFAULT_OPTION);
}
d. 程序运行:程序运行时每个功能界面截图
人机交互界面:
高频词的统计:
柱状图的显示:
统计单词数、行数以及所用时间:
输出到result.txt文件:
e. 描述结对的过程,提供两人在讨论、细化和编程时的结对照片(非摆拍)
f. 提供此次结对作业的PSP。
结对项目开发过程中,构建PSP表如下:
PSP | 任务内容 | 计划共完成需要的时间(min) | 实际完成需要的时间(min) |
---|---|---|---|
Planning | 计划 | 10 | 15 |
- Estimate | 估计这个任务需要多少时间,并规划大致工作步骤 | 10 | 15 |
Development | 开发 | 345 | 425 |
- Analysis | 需求分析 (包括学习新技术) | 20 | 25 |
- Design Spec | - 生成设计文档 | 25 | 25 |
- Design Review | - 设计复审 (和同事审核设计文档) | 25 | 20 |
- Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 20 | 25 |
- Design | 具体设计 | 45 | 50 |
- Coding | 具体编码 | 200 | 255 |
- Test | - 测试(自我测试,修改代码,提交修改) | 30 | 25 |
Reporting | 报告 | 50 | 48 |
-- Test Report | - 测试报告 | 25 | 20 |
- Size Measurement | 计算工作量 | 25 | 28 |
- Postmortem & Process Improvement Plan | - 事后总结 ,并提出过程改进计划 | 30 | 28 |
结对感受和体会:在项目正式开发之前,我们先预估本次合作开发任务的PSP环节的消耗时间,并在PSP过程中统计实际耗时,填写PSP表格。在实施项目结对过程中两个人一起沟通,共同参与程序的编码工作,通过讨论,形成了两个人都认可的编程规范,通过查阅资料等过程,最终完成了结对项目。通过此次结对项目,切身体会到了1+1>2的结对优势,并对以后的项目开发奠定了基础。