当前位置: 首页 > 编程日记 > 正文

软工作业 5:词频统计——增强功能

一、基本信息

1.1 编译环境、项目名称、作者

1 #编译环境:python3.6
2 #项目名称:软工作业5-词频统计—增强功能 3 #作者:1613072055 潘博 4 # 1613072056 侯磊

1.2项目地址

  • 本次作业地址:  https://www.cnblogs.com/panboo/
  • 项目git地址:  https://gitee.com/ntucs/PairProg/tree/SE055_056

二、项目分析

  • 程序运行模块(方法、函数)介绍

    Task 1. 接口封装 —— 将基本功能封装成(类或独立模块)

将基本功能:统计文本总词数,统计文本最多的十个单词及其词频这两个方法封装在类Core中,使用面向对象的思想将两个基本功能解耦合,

使之成为通用的方法。

 1 # encoding = utf-8
 2 import re
 3 
 4 class Core:
 5     def process_file(dst):  # 读文件到缓冲区
 6         try:  # 打开文件
 7             file1 = open(dst, "r")
 8         except IOError as s:
 9             print(s)
10             return None
11         try:  # 读文件到缓冲区
12             bvffer = file1.read()
13         except:
14             print("Read File Error!")
15             return None
16         file1.close()
17         return bvffer
18 
19     def word_count(self, bvffer):
20         #bvffer = self.process_file(dst) # 调用方法读数据到缓存区
21         try:
22             count = 0
23             # 统计行数
24             for i in bvffer:  # 统计文件内容中换行符的数目
25                 if i == '\n':
26                     count += 1
27             return count
28         except:
29             print("Read File Error!")
30 
31     def word_freq_t10(self, bvffer):
32         #bvffer = self.process_file(dst)  # 调用方法读数据到缓存区
33         stop = open("stopwords.txt", 'r', encoding='UTF-8')  # 停词表的读取
34         stop_file = stop.read()
35         stop_words = stop_file.replace('\n', " ").lower().split()
36         for i in bvffer: # 去除特殊字符
37             if i in '!"#$%&()*+-,-./:;<=>?@“”[\\]^_{|}~':
38                 bvffer = bvffer.replace(i, " ")  # 替换特殊字符
39         words = bvffer.lower().split()
40         if words:
41             Newwords = []
42             words_select = '[a-z]{4}(\w)*'  # 用正则表达式筛选合格单词
43             for i in range(len(words)):
44                 word = re.match(words_select, words[i])
45                 if word:
46                     Newwords.append(word.group())
47         # 统计单词的词频
48         word_freq = {} # 定义字典而非数组
49         for word in Newwords:
50             word_freq[word] = word_freq.get(word, 0) + 1
51         sorted_word_freq = sorted(word_freq.items(), key=lambda v: v[1], reverse=True) # 对合格单词词频排序
52         return sorted_word_freq[:10] # 返回排序数组的前十个元素

编写一个test5.py,通过import WordCount5模块,可以在cmd命令行中测试上述的封装类,也可以直接在Pycharm开发环境中测试。

 1 from SE_fifthwork_task1 import WordCount5
 2 import argparse
 3 if __name__ == '__main__':
 4     parser = argparse.ArgumentParser(description="your script description")  # description参数可以用于插入描述脚本用途的信息,可以为空
 5     parser.add_argument('--f', '-f', type=str, default='Gone_with_the_wind.txt', help="读取文件路径")
 6     args = parser.parse_args()  # 将变量以标签-值的字典形式存入args字典
 7     dst = args.f
 8     print(dst)
 9     core = WordCount5.Core()
10     bvffer = WordCount5.Core.process_file(dst)
11 
12     # 任务一 第一个要求测试
13     count = WordCount5.Core.word_count(core, bvffer)
14     print(count)
15 
16     # 任务一: 第二个要求测试
17     # sorted_word_freq = WordCount5.Core.word_freq_t10(core, bvffer)
18     # for item in sorted_word_freq:  # 输出 Top 10 的单词
19     #     print("<%s>:%d " % (item[0], item[1]))

对任务1的两个基本方法测试所得结果截图如下:

   

Task 2. 增加新功能

  • 词组统计:能统计文件夹中指定长度的词组的词频
  • 自定义输出:能输出用户指定的前n多的单词与其数量

封装类Core的代码:

 1 # encoding = utf-8
 2 import re
 3 
 4 
 5 class Core:
 6     def __init__(self, dst, m, n, o):  # dst:文件路径;m:词组长度;n:输出的单词数量
 7         self.dst = dst
 8         self.m = m
 9         self.n = n
10         self.o = o
11 
12     def process_file(self):  # 读取文件
13         try:  # 打开文件
14             file1 = open(self.dst, "r", encoding='GBK')
15         except IOError as s:
16             print(s)
17             return None
18         try:  # 读文件到缓冲区
19             bvffer = file1.read()
20         except:
21             print("Read File Error!")
22             return None
23         file1.close()
24         return bvffer
25 
26     def process_buffer(self, bvffer):
27         if bvffer:
28             chara_num = 0
29             blank = ''
30             for chara in bvffer:  # 统计字母的数目
31                 if chara.isalpha():
32                     chara_num += 1
33             count = 0
34             for i in bvffer:  # 统计文件内容中换行符的数目
35                 if i == '\n':
36                     count += 1
37             if i[-1] != '\n':  # 当文件最后一个字符不为换行符时,行数+1
38                 count += 1
39             for ch in ':,.-_':
40                 bvffer = bvffer.lower().replace(ch, " ")
41             fwords = bvffer.strip().split()
42 
43             for i in range(self.m):
44                 blank += '[a-z]+'
45                 if i < self.m - 1:
46                     blank += '\s'
47             last = re.findall(blank, bvffer)  # 正则查找词组
48             word_freq = {}
49             for word in last:  # 将正则匹配的结果进行统计
50                 word_freq[word] = word_freq.get(word, 0) + 1
51             return word_freq, chara_num, len(fwords), count
52 
53     def output_result(self, word_freq):
54         if word_freq:
55             sorted_word_freq = sorted(word_freq.items(), key=lambda v: v[1], reverse=True)
56             for item in sorted_word_freq[:self.n]:  # 输出 Top n 的单词
57                 print("<%s>:%d " % (item[0], item[1]))
58         return sorted_word_freq[:self.n]
59 
60     def print_result(self):
61         print('读入的文件路径为:' + str(self.dst))
62         print('统计词组长度为:' + str(self.m))
63         print('输出的单词数量为:' + str(self.n))
64         print('文件的存储路径为:' + str(self.o))
65         buffer = Core.process_file(self)
66         word_freq, characters, count_words, count = Core.process_buffer(self, buffer)
67         print("characters:%d " % characters)
68         print("lines:%d " % count)
69         print("words:%d " % count_words)
70         items = Core.output_result(self, word_freq)
71         f = open(self.o, 'w+')
72         print("characters:%d " % characters, file=f)
73         print("lines:%d " % count, file=f)
74         print("words:%d " % count_words, file=f)
75         for item in items:  # 格式化
76             item = '<' + str(item[0]) + '>:' + str(item[1]) + '\n'
77             f.write(item)
78         f.close()
79 
80 
81 if __name__ == '__main__':
82     test = Core('Gone_with_the_wind.txt', 3, 5, 'main.txt')
83     test.print_result()

import argparse模块进行命令行传参测试代码:

 1 # encoding = utf-8
 2 import WordCount5
 3 import argparse
 4 
 5 
 6 if __name__ == '__main__':
 7     parser = argparse.ArgumentParser(description="your script description")  # description参数可以用于插入描述脚本用途的信息,可以为空
 8     parser.add_argument('--i', '-i', type=str, default='Gone_with_the_wind.txt', help="读取的文件路径")
 9     parser.add_argument('--m', '-m', type=int, default=2, help="词组包含单词数量")
10     parser.add_argument('--n', '-n', type=int, default=5, help="输出的词组数量")
11     parser.add_argument('--o', '-o', type=str, default='result.txt', help="存储文件路径")
12     args = parser.parse_args()  # 将变量以标签-值的字典形式存入args字典
13     dst = args.i
14     m = args.m
15     n = args.n
16     o = args.o
17     test5 = WordCount5.Core(dst, m, n, o)
18     test5.print_result()

运行成果图:

    ①使用 -i 传递参数“读取的文件路径

①使用 -m 传递参数“词组包含单词数量

 

使用 -n  传递参数  “输出的词组数量

使用 -0 传递参数  “存储文件路径

     ④-0 -i -m -n 一起使用

三、性能分析

本次实验在作业4基础上进行,在时间、空间复杂度方面差不多,所以运行很流畅。

1.根据执行时间分析

2、性能图表:

四、PSP 表格

五、事后分析与总结

1 在封装Core模块时——讨论过程

  在解决封装方式时,我们两位同学在解决方法方面出现了分歧。

  55号潘博考虑在设计和实现一个客观系统时,在满足需求的条件下,把系统设计成一些不可变的(相对固定)部分组成的最小集合(最好的设计)。

这些不可变的部分就是所谓的对象。也就是使用面向对象的思想将原来我们写的作业4的项目进行分解成可复用的类方法,从而达到易维护和易扩展的

特点。

  56号侯磊同学认为使用面向过程,将所有业务逻辑写在一起,可以减少代码量并且容易实现,相对来说性能比面向对象高,因为类调用时需要实例化,开销比较大,比较消耗资源;比如单片机、嵌入式开发、Linux/Unix等一般采用面向过程开发,性能是最重要的因素。

  最后,我们综合考虑是作业要求和开发模式优缺点,决定使用潘博同学的方法。

  2 互相评价

  潘博评价侯磊:侯磊同学虽然在编程方面基础不是很好,但是在合作的过程中积极为项目做贡献,在查阅资料与学习

方面不遗余力。美中不足的是对编写程序背后的逻辑方面,不够严谨,希望以后能够多加思考。

  侯磊评价潘博:潘博同学不管在编程能力还是在技术储备方面都非常优秀,能够灵活运用已经学习的各门专业知识,

并且在代码编写与调试方面也非常熟练。在完成任务的同时,积极帮助我解答疑问,受益匪浅,期待下一次的合作。

  3 评价整个过程

  我们觉得,从本次作业完成的过程中,理解了软件工程不仅仅是一门关于程序编写与设计的学科,他还是一门包含“人”

的学科,甚至团队合作是软件开发中的至关重要的一环。

4.结对编程照片

5.其他

经过这两次的合作编程,我们双方的编程能力都有提高。在合作的过程中,我们互相学习、帮助,一起解决问题,这两次的合作对我们非常有意义。

转载于:https://www.cnblogs.com/panboo/p/10055156.html

相关文章:

Linux之文件权限管理

chmod ux转载于:https://www.cnblogs.com/chaoren399/archive/2013/03/11/2953727.html

如果三十年前有这些AI技术,可可西里的悲剧不会发生

作者 | 神经小姐姐来源 | HyperAI超神经&#xff08;ID&#xff1a;HyperAI&#xff09;而被盗猎者大量的非法捕杀。多种野生动物都处于濒临灭绝的局面&#xff0c;人工智能等技术&#xff0c;能够在帮助保护野生动物上&#xff0c;发挥比较大的作用&#xff0c;让我们能够生存…

Percona-Server-5.5.30安装

1、安装系统环境 yum install -y gcc gcc-c autoconf automake zlib* libxml* ncurses-devel libmcrypt* libtool-ltdl-devel* cmake bison 2、下载源码包 1 http://www.percona.com/downloads/ 2 3 wget -c http://www.percona.com/redir/downloads/Percona-Server-5.5/Perc…

OpenCV中SVM的使用

转自&#xff1a;http://download.csdn.net/download/gaogaogao124/3125857 略有改动&#xff1a; #include"stdafx.h" #include<opencv2/opencv.hpp> #include<cmath> #include<ctime> using namespace std; int _tmain(int argc,_TCHAR…

数据不够,用GAN来凑!

作者 | CV君来源 | 我爱计算机视觉&#xff08;ID&#xff1a;aicvml&#xff09;在计算机视觉领域&#xff0c;深度学习方法已全方位在各个方向获得突破&#xff0c;这从近几年CVPR 的论文即可看出。但这往往需要大量的标注数据&#xff0c;比如最著明的ImageNet数据集&#x…

MySQL的登陆错误:ERROR 1049 (42000): Unknown database 'root'

刚刚装上数据库的时候&#xff0c;直接按照这个格式就登陆上去了&#xff0c;突然莫名其妙登陆不上去了 但是现在突然死活登陆不上去了 于是拿着这个报错信息在网上找啊找&#xff0c;终于找了了错误的原因 -p和密码是连在一起的&#xff0c;赶紧一试&#xff0c;果然可以登陆&…

分布式缓存系统Memcached简介与实践

缘起: 在数据驱动的web开发中&#xff0c;经常要重复从数据库中取出相同的数据&#xff0c;这种重复极大的增加了数据库负载。缓存是解决这个问题的好办法。但是ASP.NET中的虽然已经可以实现对页面局部进行缓存&#xff0c;但还是不够灵活。此时Memcached或许是你想要的。Memca…

Windows7 libsvm库中grid.py的使用步骤

1、从http://www.csie.ntu.edu.tw/~cjlin/libsvm/下载最新的libsvm-3.12库(libsvm-3.12.tar.gz或libsvm-3.12.zip)&#xff0c;将其放到F:\libsvm文件夹下解压缩&#xff0c;生成一个libsvm-3.12文件夹&#xff1b; 2、从http://www.gnuplot.info/下载最新的gnuplot即gp460-wi…

基于GEMM实现的CNN底层算法被改?Google提出全新间接卷积算法

作者 | Marat Dukhan from Google Research译者 | 凯隐责编 | Jane出品 | AI科技大本营&#xff08;ID: rgznai100&#xff09;【导读】本文介绍的内容主要聚焦Google 的一项最新工作&#xff1a;改变基于 GEMM 实现的 CNN底层算法提出的新方法。通用矩阵乘法&#xff08;Gener…

共享内存跨进程通信

通过共享内存通信是最快的&#xff0c;不过既然是共享资源&#xff0c;那么就必须要有同步机制。 创建共享内存有两种方式shm和mmap的方式。 mmap是在磁盘上建立一个文件&#xff0c;每个进程地址空间中开辟出一块空间进行映射。而对于shm而言&#xff0c;shm每个进程最终会映射…

扶稳!四大步“上手”超参数调优教程,就等你出马了 | 附完整代码

作者 | Matthew Stewart译者 | Monanfei责编 | Jane出品 | AI科技大本营&#xff08;ID: rgznai100&#xff09;【导读】在本文中&#xff0c;我们将为大家介绍如何对神经网络的超参数进行优化调整&#xff0c;以便在 Beale 函数上获得更高性能&#xff0c;Beale 函数是评价优化…

读好书,写好程序

本人是做.NET开发的&#xff0c;以企业应用为主&#xff0c;以互联网为爱好&#xff0c;这里给大家推荐一些适合.NET程序员的书&#xff1a; 软件设计《企业应用架构模式》 Martin Fowler 的大作之一&#xff0c;总结了多种常见的企业应用架构模式&#xff0c;这些模式是脱离具…

SIFT特征点匹配中KD-tree与Ransac算法的使用

转自&#xff1a;http://blog.csdn.net/ijuliet/article/details/4471311 Step1:BBF算法&#xff0c;在KD-tree上找KNN。第一步做匹配咯~ 1.什么是KD-tree&#xff08;fromwiki&#xff09; K-Dimension tree&#xff0c;实际上是一棵平衡二叉树。 一般的KD-tree构造过程&a…

jQuery带缩略图的宽屏焦点图插件

在线演示 本地下载

追溯XLNet的前世今生:从Transformer到XLNet

作者丨李格映来源 | 转载自CSDN博客导读&#xff1a;2019 年 6 月&#xff0c;CMU 与谷歌大脑提出全新 XLNet&#xff0c;基于 BERT 的优缺点&#xff0c;XLNet 提出一种泛化自回归预训练方法&#xff0c;在 20 个任务上超过了 BERT 的表现&#xff0c;并在 18 个任务上取得了当…

微软MCITP系列课程

http://liushuo890.blog.51cto.com/5167996/d-1转载于:https://blog.51cto.com/showcart/1156172

在Ubuntu11.10中安装配置OpenCV2.3.1和CodeBlocks

1、 打开终端&#xff1b; 2、 执行指令&#xff0c;删除ffmpeg and x264旧版本&#xff1a;sudo apt-get removeffmpeg x264 libx264-dev 3、下载安装x264和ffmpeg所有的依赖&#xff1a;sudo apt-get update sudo apt-get installbuild-essential checkinstall git cmake…

深入浅出Rust Future - Part 1

本文译自Rust futures: an uneducated, short and hopefully not boring tutorial - Part 1&#xff0c;时间&#xff1a;2018-12-02&#xff0c;译者:motecshine, 简介&#xff1a;motecshine 欢迎向Rust中文社区投稿,投稿地址,好文将在以下地方直接展示 Rust中文社区首页Rust…

cmd 修改文件属性

现在的病毒基本都会采用一种方式&#xff0c;就是将病毒文件的属性设置为系统隐藏属性以逃避一般用户的眼睛&#xff0c;而且由于Windows系统的关系&#xff0c;这类文件在图形界面下是不能修改其属性的。但是好在Windows还算做点好事&#xff0c;留下了一个attrib命令可以让我…

Django 视图

Django之视图 目录 一个简单的视图CBV和FBV FBV版&#xff1a;CBV版&#xff1a;给视图加装饰器 使用装饰器装饰FBV使用装饰器装饰CBVrequest对象 请求相关的常用值属性方法Response对象 使用属性JsonResponse对象Django shortcut functions render()redirect()Django的View&am…

喜大普奔!GitHub官方文档推出中文版

原创整理 | Python开发者&#xff08;ID&#xff1a;PythonCoder&#xff09;最近程序员交友圈出了一个大新闻&#xff0c;GitHub 帮助文档正式推出中文版了&#xff0c;之前一直都是只有英文文档&#xff0c;看起来费劲不方便。这份中文文当非常详尽&#xff0c;可以说有了它 …

Linux中获取当前程序路径的方法

1、命令行实现&#xff1a;转自&#xff1a;http://www.linuxdiyf.com/viewarticle.php?id84177 #!/bin/sh cur_dir$(pwd) echo $cur_dir 注意&#xff1a;在cur_dir后没空格&#xff0c;后面也不能有空格&#xff0c;不然它会认为空格不是路径而报错 2、程序实现&#xf…

android 关于字符转化问题

今日在写android的客户端&#xff0c;发现字符转化是个大问题。 下面是Unicode转UTF-8的转化&#xff0c;便于以后使用 private static String decodeUnicode(String theString) { char aChar; int len theString.length(); StringBuffer outBuffer new Strin…

30分钟看懂XGBoost的基本原理

作者 | 梁云1991转载自Python与算法之美&#xff08;ID: Python_Ai_Road&#xff09;一、XGBoost和GBDTxgboost是一种集成学习算法&#xff0c;属于3类常用的集成方法(bagging,boosting,stacking)中的boosting算法类别。它是一个加法模型&#xff0c;基模型一般选择树模型&…

Linux下遍历文件夹的实现

转自&#xff1a;http://blog.csdn.net/wallwind/article/details/7528474 linux C 遍历目录及其子目录 #include <stdio.h> #include <string.h> #include <stdlib.h> #include <dirent.h> #include <sys/stat.h> #include <unistd.h&…

如何用Python画一棵漂亮的树

Tree海龟绘图turtle 在1966年&#xff0c;Seymour Papert和Wally Feurzig发明了一种专门给儿童学习编程的语言——LOGO语言&#xff0c;它的特色就是通过编程指挥一个小海龟&#xff08;turtle&#xff09;在屏幕上绘图。 海龟绘图&#xff08;Turtle Graphics&#xff09;后来…

windows7下,Java中利用JNI调用c++生成的动态库的使用步骤

1、从http://www.oracle.com/technetwork/java/javase/downloads/jdk-7u2-download-1377129.html下载jdk-7u2-windows-i586.exe&#xff0c;安装到D:\ProgramFiles\Java&#xff0c;并将D:\ProgramFiles\Java\jdk1.7.0_02\bin添加到环境变量中&#xff1b; 2、从http://www.ec…

外观模式 - 设计模式学习

外观模式(Facade)&#xff0c;为子系统中的一组接口提供一个一致的界面&#xff0c;此模式定义了一个高层接口&#xff0c;这个接口使得这一子系统更加容易使用。 怎么叫更加容易使用呢&#xff1f;多个方法变成一个方法&#xff0c;在外观看来&#xff0c;只需知道这个功能完成…

Google最新论文:大规模深度推荐模型的特征嵌入问题有解了!

转载自深度传送门&#xff08;ID: gh_5faae7b50fc5&#xff09;导读&#xff1a;本文主要介绍下Google在大规模深度推荐模型上关于特征嵌入的最新论文。 一、背景大部分的深度学习模型主要包含如下的两大模块&#xff1a;输入模块以及表示学习模块。自从NAS[1]的出现以来&#…

[20181204]低版本toad 9.6直连与ora-12505.txt

[20181204]低版本toad 9.6直连与ora-12505.txt--//我们生产系统还保留有一台使用AMERICAN_AMERICA.US7ASCII字符集的数据库,这样由于toad新版本不支持该字符集的中文显示.--//我一直保留toad 9.6的版本,并且这个版本是32位的,我必须在我的机器另外安装10g 32位版本的客户端,这样…