实验四 软件工程界对项目
博文简要信息:
项目 | 内容 |
---|---|
这个作业属于哪个课程 | 【教师博客主页链接】 |
这个作业的要求在哪里 | 【作业链接地址】 |
课程学习目标 | 熟悉软件开发整体流程,提升自身能力 |
本次作业在哪个具体方面帮助我们实现目标 | 第一次体验一个完整的工程 |
实验内容:
任务 | 内容 |
---|---|
任务一 | 两两自由结对,对结对方的《实验二 软件工程个人项目》的项目成果进行评价 |
任务二 | 采用两人合作方式,设计开发一个英文文本统计分析软件 |
任务三 | 完成博文作业 |
任务一 组队互评
项目 | 内容 |
---|---|
作业博客 | 【张旭辉201671010459】 |
点评内容 | 实验结果很明了,实现的功能和欠缺的都很明显,再补充编程方面的能力会做的更好。 |
点评心得 | 编程语言的短板是绝对的硬伤,于人于已都是如此,当下恶补短板才是正道。 |
Github仓库主页 | 【仓库地址】 |
任务二 合作设计
1.需求分析
-
实验2要求的功能;
-
单词频数可视化柱状图要求是以下样式:
-
统计该文本行数及字符数;
-
各种统计功能均提供计时功能,显示程序统计所消耗时间(单位:ms);
-
可处理任意用户导入的任意英文文本;
-
人机交互界面要求GUI界面(WEB页面、APP页面都可);
-
附加分功能:统计文本中除冠词、代词、介词之外的高频词;
-
附加分功能:统计前10个两个单词组成的词组频率。
2.软件设计:类关键信息
-
BufferedReader(Reader in,int sz)类
创建一个使用指定大小输入缓冲区的缓冲字符输入流
-
JFreeChart类
字符串中的字母被转换为小写字母,开放的图表绘制类库,用于生成柱形图,可以产生PNG文件
-
CategoryPlot类
实现对数组的排序,给输出的单词频率高低进行排序,组合图形
-
SimpleDateFormat类
以与语言环境相关的方式来格式化和分析日期的具体类
-
Map<String ,Integer>map接口
map接口,以键值对方存储单词词频
-
File类
File对象用来获取或处理与磁盘文件相关的信息,例如权限,时间,日期和目录路径
-
ServletInputStream类
一个 Servlet 通过使用ServletRequest 接口获得了对一ServletInputStream 对象的说明。这个类的子类必须提供一InputStream接口读取有关信息的方法
-
Collection类
集合接口
uml图:
3.核心功能代码展示
/**
* 柱状图设置文字样式
* @param chart
*/
private static void getChartByFont(JFreeChart chart,Integer end) {
// 图形设置标题文字
TextTitle textTitle = chart.getTitle();
textTitle.setFont(new Font("宋体", Font.BOLD, 32));
//设置X轴内容竖直
// XYPlot xyplot = chart.getXYPlot();
// DateAxis dateaxis = (DateAxis)xyplot.getDomainAxis();
// dateaxis.setTickUnit(new DateTickUnit(1, 1, new SimpleDateFormat("MMM-yyyy")));
// dateaxis.setVerticalTickLabels(true);
// 设置图形X轴坐标文字
CategoryPlot plot = (CategoryPlot) chart.getPlot();
CategoryAxis axis = plot.getDomainAxis();
axis.setLabelFont(new Font("宋体", Font.BOLD, 8)); // 设置X轴坐标上标题的文字
axis.setTickLabelFont(new Font("宋体", Font.BOLD, 16)); // 设置X轴坐标上的文字
axis.setCategoryLabelPositions(CategoryLabelPositions.DOWN_45);
axis.setUpperMargin(0.01);//设置距离图片左端距离
axis.setLowerMargin(0.01); //设置距离图片右端距离
// 设置图形Y轴坐标文字
NumberAxis na= (NumberAxis)plot.getRangeAxis();
na.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
ValueAxis valueAxis = plot.getRangeAxis();
valueAxis.setLabelFont(new Font("宋体", Font.BOLD, 20)); // 设置Y轴坐标上标题的文字
valueAxis.setTickLabelFont(new Font("sans-serif", Font.BOLD, 16));// 设置Y轴坐标上的文字
valueAxis.setRange(0,end);
// valueAxis.setLowerBound(0); //Y轴以开始的最小值
// valueAxis.setUpperBound(15); //Y轴的最大值
// 设置提示内容的文字
chart.getLegend().setItemFont(new Font("宋体", Font.BOLD, 24));
}
}
public class InputFile {
/**
* 文件名生成
* @return
*/
public static String getRandomFileName() {
SimpleDateFormat simpleDateFormat;
simpleDateFormat = new SimpleDateFormat("yyyyMMdd");
Date date = new Date();
String str = simpleDateFormat.format(date);
Random random = new Random();
int rannum = (int) (random.nextDouble() * (99999 - 10000 + 1)) + 10000;// 获取5位随机数
return rannum + str;// 当前时间
}
/**
* 单词:词频
* @param file
* @return
*/
public class FileServlet extends HttpServlet{
private static final long serialVersionUID = 1L;
public FileServlet() {
super();
}
/**
* 存入文件
*/
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
/**
* 读取文件
*/
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("utf-8");
//String contentType = request.getContentType();
//System.out.println("表单类型:"+contentType);
//String boundary = contentType.substring(contentType.indexOf("boundary=")+9);
//System.out.println("boundary:"+boundary);
String root = getServletContext().getRealPath("/tempFile/temp.txt");
File file = new File(root);
if(!file.exists()){
//先得到文件的上级目录,并创建上级目录,在创建文件
file.getParentFile().mkdir();
try {
//创建文件
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
public class JfreeChartServlet extends HttpServlet{
/**
* 柱状图生成
* @return
*/
private static final long serialVersionUID = 1L;
public JfreeChartServlet() {
super();
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
@SuppressWarnings("null")
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setHeader("Content-Type", "textml;charset=UTF-8");
String root = getServletContext().getRealPath("/tempFile/temp.txt");
File readfile = new File(root);
//System.out.println(readfile.exists());
if(readfile.exists()){
InputFile in = new InputFile();
Map<String,Integer> readmap = in.readFile(readfile);
//System.out.println(readmap);
//取出单词词频最大数值
Collection<Integer> c = readmap.values();
Object[] obj = c.toArray();
Arrays.sort(obj);
// System.out.println("单词词频数:"+Arrays.toString(obj));
// System.out.println("最大词频:"+obj[obj.length-1]);
Integer maxnumber = (Integer) obj[obj.length-1];
System.out.println("单词数:"+obj.length);
//遍历
DefaultCategoryDataset dataset = new DefaultCategoryDataset();
for (String key : readmap.keySet()) {
Integer value = readmap.get(key); //得到每个key所对应的value值
dataset.addValue(value, "单词", key);
}
// 获取柱状图工具类创建的柱状图,(将数据集传入)
JFreeChart chart = ColumnarTools.createCoColumnar(dataset,maxnumber+1);
new InputFile();
//以当前时间生成图片名称(防止图片重复被覆盖)
String time = InputFile.getRandomFileName();
String uploadUrl = request.getServletContext().getRealPath("/")+"images\"+time+".png";
System.out.println("图片物理路径所在位置:"+uploadUrl);
File file = new File(uploadUrl);
//System.out.println(file);
if(!file.exists()){
//先得到文件的上级目录,并创建上级目录,在创建文件
file.getParentFile().mkdir();
try {
//创建文件
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
ChartUtilities.saveChartAsJPEG(file, chart, 800, 600);
Map<String, String> map = new HashMap<String, String>();
map.put("name", time+".png");
JSONObject jsonObject = JSONObject.fromObject(map);
System.out.println("json图片名称:"+jsonObject);
response.getWriter().write(jsonObject.toString());
}
4.程序运行
选择txt文本:
读取txt,分离单词:
查询单词频率:
显示统计柱状图:
5.过程及照片
6.PSP
PSP2.1 | 任务内容 | 计划共完成需要的时间(min) | 实际完成需要的时间(min) |
---|---|---|---|
Planning | 计划 | 10 | 15 |
Estimate | 估计这个任务需要多少 时间,并规划大致工作步骤 | 10 | |
Development | 开发 | 300 | 400 |
Analysis | 需求分析 (包括学习新技术) | 15 | 20 |
Design Spec | 生成设计文档 | 15 | 30 |
Design Review | 设计复审 (和同学审核设计文档) | 16 | 23 |
Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 5 | 9 |
Design | 具体设计 | 20 | 30 |
Coding | 具体编码 | 180 | 240 |
Code Review | 代码复审 | 20 | 30 |
Test | 测试(自我测试,修改代码,提交修改) | 50 | 50 |
Reporting | 报告 | 25 | 30 |
Test Report | 测试报告 | 6 | 8 |
Size Measurement | 计算工作量 | 5 | 5 |
Postmortem & Process Improvement Plan | 事后总结 ,并提出过程改进计划 | 9 | 12 |
实验小结
每个人的性格不一样,有的比较直率外向,有的则比较含蓄内向,如果两个人互相学习,互相帮助取长补短,就会刚柔相济,和谐相处。一个人的智慧和能力也是有限的,每个人都应该把自己的优势与大家分享,利用别人的优势来弥补自己的不足。人与人的合作不是人力的简单相加,还需要真诚的态度,优势的互补,只有这样才会实现双赢,实现1+1>2的效果。