福州大学软件工程实践个人编程作业
这个作业属于哪个课程 | https://edu.cnblogs.com/campus/fzu/SE2020 |
---|---|
这个作业要求在哪里 | https://edu.cnblogs.com/campus/fzu/SE2020/homework/11167 |
这个作业的目标 | github的使用;json解析 |
学号 | 031802520 |
目录
·PSP表格
·解题思路
·设计实现过程
·代码说明
·单元测试
·单元测试覆盖率优化
·性能优化
·代码规范链接
·总结
PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 60 | 90 |
Estimate | 估计这个任务需要多少时间 | 30 | 30 |
Development | 开发 | 120 | 180 |
Analysis | 需求分析 | 240 | 250 |
Design Spec | 生成设计文档 | 30 | 30 |
Design Review | 设计复审 | 30 | 60 |
Coding Standard | 代码规范 | 5 | 10 |
Design | 具体设计 | 30 | 50 |
Coding | 具体编码 | 120 | 240 |
Coding Review | 代码复审 | 40 | 60 |
Test | 测试 | 30 | 60 |
Reporting | 报告 | 30 | 60 |
Test Report | 测试报告 | 20 | 20 |
Size Measurement | 计算工作量 | 50 | 60 |
Postmortem & Process Improvement Plan | 总结, 思考如何优化 | 50 | 60 |
合计 | 885 | 1230 |
解题思路
然后看了这题感觉无从下手,就先学习老师的b站视频,学习到基本的git的使用。问了问大佬,了解了这题是要解析json。样例代码给的
是python,大佬也说python写起来方便,可是菜鸡如我只会C++。同学推荐我用慕课网上的免费文字课程,于是从0开始学习python。学
习了用递归遍历文件夹后取文件逐行解析。对于数据分析,同学建议用正则表达式的匹配优化。对于示例程序的递归展开部分运行了许多
冗余信息,直接遍历搜索更快。
设计实现过程
代码说明
注:说明在注释当中
# -*- coding: utf-8 -*-
import os
import argparse
import pickle
import re
DATA = ("PushEvent", "IssueCommentEvent", "IssuesEvent", "PullRequestEvent" )
# 匹配时使用
pattern = re.compile(r'"type":"(\w+?)".*?actor.*?"login":"(\S+?)".*?repo.*?"name":"(\S+?)"')
# 正则表达式的使用,优化匹配速度
class Data:
def __init__(self):
self._user = {}
self._repo = {}
self._user_repo = {}
# 初始化记录读取的内存
# 可使函数无参使用
@staticmethod
def __parse(file_path: str):
records = []
# 打开json文件
with open(file_path, 'r', encoding='utf-8') as f:
for line in f:
# 运用正则表达式匹配有效数据
res = pattern.search(line)
if res is None or res[1] not in DATA:
continue
records.append(res.groups())
return records
def init(self, dir_path: str):
records = []
# 跑目录
for cur_dir, sub_dir, filenames in os.walk(dir_path):
filenames = filter(lambda r: r.endswith('.json'), filenames)
for name in filenames:
records.extend(self.__parse(f'{cur_dir}/{name}'))
for record in records:
event, user, repo = record
# 取值或创建
self._user.setdefault(user, {})
self._user_repo.setdefault(user, {})
self._repo.setdefault(repo, {})
self._user_repo[user].setdefault(repo, {})
self._user[user][event] = self._user[user].get(event, 0)+1
self._repo[repo][event] = self._repo[repo].get(event, 0)+1
self._user_repo[user][repo][event] = self._user_repo[user][repo].get(event, 0)+1
with open('1.json', 'wb') as f:
pickle.dump(self._user, f)
with open('2.json', 'wb') as f:
pickle.dump(self._repo, f)
with open('3.json', 'wb') as f:
pickle.dump(self._user_repo, f)
def load(self):
if not any((os.path.exists(f'{i}.json') for i in range(1, 3))):
raise RuntimeError('error: data file not found')
with open('1.json', 'rb') as f:
self._user = pickle.load(f)
with open('2.json', 'rb') as f:
self._repo = pickle.load(f)
with open('3.json', 'rb') as f:
self._user_repo = pickle.load(f)
def get_user(self, user: str, event: str) -> int:
return self._user.get(user, {}).get(event, 0)
def get_repo(self, repo: str, event: str) -> int:
return self._repo.get(repo, {}).get(event, 0)
def get_user_repo(self, user: str, repo: str, event: str) -> int:
return self._user_repo.get(user, {}).get(repo, {}).get(event, 0)
class Run:
# 参数设置
def __init__(self):
self.parser = argparse.ArgumentParser()
self.data = None
self.arg_init()
# 设置可能有的参数,便于解析
def arg_init(self):
self.parser.add_argument('-i', '--init', type=str)
self.parser.add_argument('-u', '--user', type=str)
self.parser.add_argument('-r', '--repo', type=str)
self.parser.add_argument('-e', '--event', type=str)
def analyse(self):
args = self.parser.parse_args()
self.data = Data()
if args.init:
self.data.init(args.init)
return 'init done'
self.data.load()
if not args.event:
raise RuntimeError('error: the following arguments are required: -e/--event')
if not args.user and not args.repo:
raise RuntimeError('error: the following arguments are required: -u/--user or -r/--repo')
# 判断询问
if args.user and args.repo:
res = self.data.get_user_repo(args.user, args.repo, args.event)
elif args.user:
res = self.data.get_user(args.user, args.event)
else:
res = self.data.get_repo(args.repo, args.event)
return res
if __name__ == '__main__':
a = Run()
print(a.analyse())
单元测试
单元测试覆盖率优化
性能优化
正则表达式的匹配优化
对于冗余数据的不处理
代码规范链接
总结
这次的作业对于我而言,是非常难的,平时码的都是算法题,
没有任何开发经验,从最开始有点无从下手,慢慢摸索直至
走上正轨。学习的过程中可以多多询问他人,这样事半功倍。
这次的作业让我明白,还有很多的东西要学,目前的知识还
是太匮乏了。