201671010409 达选奇 《英文文本统计分析》结对项目报告

实验四 软件工程界对项目


博文简要信息:

项目 内容
软件工程 教师博客主页链接
作业要求 作业链接地址
课程目标 熟悉软件开发整体流程,提升自身能力
实现目标 第一次体验一个完整的工程

实验内容:

任务 内容
任务一 两两自由结对,对结对方的《实验二 软件工程个人项目》的项目成果进行评价
任务二 采用两人合作方式,设计开发一个英文文本统计分析软件
任务三 完成博文作业

任务一 组队互评

项目 内容
作业博客 丁家辉201671010406
点评内容 博文脉络清晰,博文结构中有需求分析、功能设计、环境需求、测试运行、部分代码、psp、运行截图、设计实现等功能模块,结构符合规范。博文内容每一模块 都联系该程序的相应功能模块来说,内容以程序实际运行状况为依据进行总结,内容紧凑。博文排版结构与psp中任务内容列的关系大致上保持同步,在对psp 中的“计划完成需要的时间”和“实际完成需要的时间”的两列数据进行比较发现,很多完成时间和预估时间存在差异,一方面是因为理论上的估算时间和现实的工 程进行时的时间是有区别的,另一方面在实际操作中因为对C语言编程的掌握程度不同,从而影响程序的一系列相关的进程的开发。软件结构设计比较合理,代码规范有待进一步加强,其中高频词、柱状图功能没有实现,人机交互只有两项,略显少。
点评心得 总的来说实现功能较少,还用加强java编程学习
Github仓库主页 https://github.com/Hero-ding/Hero/tree/master/词频统计

任务二 合作设计

结对项目源码在Github的仓库主页链接地址:https://github.com/Daxuanqi/ptdm/tree/master/实验四

1.需求分析

  • 实验2要求的功能;

  • 单词频数可视化柱状图要求是以下样式:

  • 统计该文本行数及字符数;

  • 各种统计功能均提供计时功能,显示程序统计所消耗时间(单位:ms);

  • 可处理任意用户导入的任意英文文本;

  • 人机交互界面要求GUI界面(WEB页面、APP页面都可);

  • 附加分功能:统计文本中除冠词、代词、介词之外的高频词;

  • 附加分功能:统计前10个两个单词组成的词组频率。

2.软件设计:类关键信息

  • BufferedReader(Reader in,int sz)类

      创建一个使用指定大小输入缓冲区的缓冲字符输入流
    
  • JFreeChart类

      字符串中的字母被转换为小写字母,开放的图表绘制类库,用于生成柱形图,可以产生PNG文件
    
  • CategoryPlot类

      实现对数组的排序,给输出的单词频率高低进行排序
    
  • SimpleDateFormat类

      以与语言环境相关的方式来格式化和分析日期的具体类
    
  • Map<String ,Integer>map接口

      以键值对方存储单词词频
    
  • File类

       File对象用来获取或处理与磁盘文件相关的信息,例如权限,时间,日期和目录路径
    
  • ServletInputStream类

       一个 Servlet 通过使用ServletRequest 接口获得了对一ServletInputStream 对象的说明。这个类的子类必须提供一InputStream接口读取有关信息的方法
    
  • Collection集合接口

      集合接口
    

uml图

![](https://img2018.cnblogs.com/blog/1614530/201904/1614530-20190403081819923-616491803.png)

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

实验小结

通过这次结对编程项目,我对多人结对的工作模式有了更深刻的理解,对软件工程的复杂性有了清楚的认识,同时对这次编程中暴露的问题有了充分的思想准备,希望在以后学习中加强编程的功底。
posted @ 2019-04-03 08:49  达选奇  阅读(198)  评论(2编辑  收藏  举报