• 201671010459张旭辉《英文文本统计分析》结对项目报告


    实验四 软件工程界对项目


    博文简要信息:

    项目 内容
    这个作业属于哪个课程 教师博客主页链接
    这个作业的要求在哪里 作业链接地址
    课程学习目标 熟悉软件开发整体流程,提升自身能力
    本次作业在哪个具体方面帮助我们实现目标 第一次体验一个完整的工程

    实验内容:

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

    任务一 组队互评

    项目 内容
    作业博客 达选奇201671010409
    点评内容 博文脉络清晰,博文结构中有需求分析、功能设计、环境需求、测试运行、部分代码、psp、运行截图、设计实现等功能模块,结构符合规范。从博文排版可看出,对于mackbook编辑器排版功能使用不是很熟练,基本符合规范。在对psp 中的“计划完成需要的时间”和“实际完成需要的时间”的两列数据进行比较发现,很多完成时间和预估时间存在差异,一方面是因为理论上的估算时间和现实的工 程进行时的时间是有区别的,另一方面在实际操作中因为对C语言编程的掌握程度不同,从而影响程序的一系列相关的进程的开发。软件结构设计比较合理,代码规范有待进一步加强,其中高频词、柱状图功能没有实现,人机交互只有两项,略显少,主要还是对于编程语言使用不熟练,知识比较缺乏,还需要加强编程能力的训练
    点评心得 对于我们初次使用mackbook,各种排版不是很完美。在对与缺少Java编程语言的相关技能,编程过程中出现的代码问题较多。没有很好的实现所有功能。

    任务二 合作设计

    1.需求分析

    • 实验2要求的功能;
    • 单词频数可视化柱状图要求是以下样式:
    • 统计该文本行数及字符数;
    • 各种统计功能均提供计时功能,显示程序统计所消耗时间(单位:ms);
    • 可处理任意用户导入的任意英文文本;
    • 人机交互界面要求GUI界面(WEB页面、APP页面都可);
    • 附加分功能:统计文本中除冠词、代词、介词之外的高频词;
    • 附加分功能:统计前10个两个单词组成的词组频率。

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

    • BufferedReader(Reader in,int sz)类

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

        开放的图表绘制类库,用于生成柱形图,可以产生PNG文件。
      
    • CategoryPlot类

        组合图形
      
    • SimpleDateFormat类

        以与语言环境相关的方式来格式化和分析日期的具体类
      
    • Date

        类 Date 表示特定的瞬间,精确到毫秒
      
    • Map<String ,Integer>map接口

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

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

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

        集合接口
      

    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.程序运行

    ![](https://img2018.cnblogs.com/blog/1614544/201904/1614544-20190403091947328-1738852808.png) ![](https://img2018.cnblogs.com/blog/1614544/201904/1614544-20190403092002738-400640189.png) ![](https://img2018.cnblogs.com/blog/1614544/201904/1614544-20190403080009294-2002486315.png)

    5.过程及照片

    6.PSP

    PSP2.1 任务内容 计划共完成需要的时间(min) 实际完成需要的时间(min)
    Planning 计划 10 15
    Estimate 估计这个任务需要多少 时间,并规划大致工作步骤 10 20
    Development 开发 300 600
    Analysis 需求分析 (包括学习新技术) 30 60
    Design Spec 生成设计文档 15 30
    Design Review 设计复审 (和同学审核设计文档) 30 45
    Coding Standard 代码规范 (为目前的开发制定合适的规范) 10 10
    Design 具体设计 30 50
    Coding 具体编码 200 500
    Code Review 代码复审 20 30
    Test 测试(自我测试,修改代码,提交修改) 40 60
    Reporting 报告 30 30
    Test Report 测试报告 6 8
    Size Measurement 计算工作量 5 5
    Postmortem & Process Improvement Plan 事后总结 ,并提出过程改进计划 9 12

    GitHub代码地址

    实验小结

    从此次实验项目,我们小组都努力的去完成这个工作,但在这个过程中,深刻认识到了团队的重要性。从中体现了各种问题,也让我们很苦恼,但最后我们都一一解决。还有我们每个人缺乏的编程能力,这是一大硬伤,我们在之后还需加大对编程能力的提高。

  • 相关阅读:
    Heritrix 3.1.0 源码解析(二十五)
    Heritrix 3.1.0 源码解析(二十八)
    获取某年某月的第一天和最后一天的Sql Server函数
    C# ToString()用法汇总
    数据库隐式类型转换
    sql server 中 SET identity_insert on
    Linq To DataTable
    ASP.NET Session详解[转载]
    CSS overflow 属性
    HTML相对路径(Relative Path)和绝对路径(Absolute Path)
  • 原文地址:https://www.cnblogs.com/16rgzxh/p/10646243.html
Copyright © 2020-2023  润新知