制作一个程序统计和分析 GitHub 的用户行为数据。
GH Archive
GH Archive 是一个 GitHub 归档数据的下载地址,它提供了从 2011 年至今的 GitHub 活动数据。
点击下载示例数据
本题关注以下这几种信息类型:
需要统计以下内容
GHAnalysis
,拓展名依所选语言而定,注意 Linux 操作系统文件系统区分大小写。GHAnalysis <--init|-i> <path to data>
java -Dfile.encoding=UTF-8 -jar GHAnalysis.jar <--init|-i> <path to data>
python3 GHAnalysis.py <--init|-i> <path to data>
GHAnalysis <-u|--user> user <-e|--event> <PushEvent|IssueCommentEvent|IssuesEvent|PullRequestEvent>
java -Dfile.encoding=UTF-8 -jar GHAnalysis.jar <-u|--user> user <-e|--event> <PushEvent|IssueCommentEvent|IssuesEvent|PullRequestEvent>
python3 GHAnalysis.py <-u|--user> user <-e|--event> <PushEvent|IssueCommentEvent|IssuesEvent|PullRequestEvent>
GHAnalysis user/repo <-r|--repo> user/repo <-e|--event> <push|IssueCommentEvent|IssuesEvent|PullRequestEvent>
java -Dfile.encoding=UTF-8 -jar GHAnalysis.jar <-r|--repo> user/repo <-e|--event> <PushEvent|IssueCommentEvent|IssuesEvent|PullRequestEvent>
python3 GHAnalysis.py <-r|--repo> user/repo <-e|--event> <PushEvent|IssueCommentEvent|IssuesEvent|PullRequestEvent>
GHAnalysis <-u|--user> user <-r|--repo> user/repo <-e|--event> <PushEvent|IssueCommentEvent|IssuesEvent|PullRequestEvent>
java -Dfile.encoding=UTF-8 -jar GHAnalysis.jar <-u|--user> user <-r|--repo> user/repo <-e|--event> <PushEvent|IssueCommentEvent|IssuesEvent|PullRequestEvent>
python3 GHAnalysis.py <-u|--user> user <-r|--repo> user/repo <-e|--event> <PushEvent|IssueCommentEvent|IssuesEvent|PullRequestEvent>
<path to data>
是一个文件夹。为了保证你的代码能够帮助更多的人,并且能得到有效的管理和开源共享,请先学习 GitHub 使用:
为了其他同仁可以轻松的阅读你的代码,请制定属于你的代码规范,要求不能偏离主流代码规范:
请参照 《码出高效_阿里巴巴Java开发手册》/《腾讯c++代码规范》/《Python PEP8》,从以下几个角度制定你的编程规范,并撰写成 Markdown 文件,请牢记你制定的编码规范,并在此次作业中严格执行。
给出此次作业的 PSP 表格。
解题思路描述。即刚开始拿到题目后,如何思考,如何找资料的过程。
设计实现过程。设计包括代码如何组织,关键函数的流程图。
代码说明。展示出项目关键代码,并解释思路。
单元测试截图和描述。
单元测试覆盖率优化和性能测试,性能优化截图和描述。
给出你的代码规范的链接,即你的仓库中的 codestyle.md。
总结本次作业。
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟)| 实际耗时(分钟)
--|:--:|--:|--:
Planning|计划||
Estimate|估计这个任务需要多少时间||
Development|开发||
Analysis|需求分析 (包括学习新技术)||
Design Spec|生成设计文档||
Design Review|设计复审||
Coding Standard|代码规范 (为目前的开发制定合适的规范)||
Design|具体设计||
Coding|具体编码||
Code Review|代码复审||
Test|测试(自我测试,修改代码,提交修改)||
Reporting|报告||
Test Report|测试报告||
Size Measurement|计算工作量||
Postmortem & Process Improvement Plan|事后总结, 并提出过程改进计划||
|合计|||
import json
import os
import argparse
class Data:
def __init__(self, dict_address: int = None, reload: int = 0):
if reload == 1:
self.__init(dict_address)
if dict_address is None and not os.path.exists('1.json') and not os.path.exists('2.json') and not os.path.exists('3.json'):
raise RuntimeError('error: init failed')
x = open('1.json', 'r', encoding='utf-8').read()
self.__4Events4PerP = json.loads(x)
x = open('2.json', 'r', encoding='utf-8').read()
self.__4Events4PerR = json.loads(x)
x = open('3.json', 'r', encoding='utf-8').read()
self.__4Events4PerPPerR = json.loads(x)
def __init(self, dict_address: str):
json_list = []
for root, dic, files in os.walk(dict_address):
for f in files:
if f[-5:] == '.json':
json_path = f
x = open(dict_address+'\\'+json_path,
'r', encoding='utf-8').read()
str_list = [_x for _x in x.split('\n') if len(_x) > 0]
for i, _str in enumerate(str_list):
try:
json_list.append(json.loads(_str))
except:
pass
records = self.__listOfNestedDict2ListOfDict(json_list)
self.__4Events4PerP = {}
self.__4Events4PerR = {}
self.__4Events4PerPPerR = {}
for i in records:
if not self.__4Events4PerP.get(i['actor__login'], 0):
self.__4Events4PerP.update({i['actor__login']: {}})
self.__4Events4PerPPerR.update({i['actor__login']: {}})
self.__4Events4PerP[i['actor__login']][i['type']
] = self.__4Events4PerP[i['actor__login']].get(i['type'], 0)+1
if not self.__4Events4PerR.get(i['repo__name'], 0):
self.__4Events4PerR.update({i['repo__name']: {}})
self.__4Events4PerR[i['repo__name']][i['type']
] = self.__4Events4PerR[i['repo__name']].get(i['type'], 0)+1
if not self.__4Events4PerPPerR[i['actor__login']].get(i['repo__name'], 0):
self.__4Events4PerPPerR[i['actor__login']].update({i['repo__name']: {}})
self.__4Events4PerPPerR[i['actor__login']][i['repo__name']][i['type']
] = self.__4Events4PerPPerR[i['actor__login']][i['repo__name']].get(i['type'], 0)+1
with open('1.json', 'w', encoding='utf-8') as f:
json.dump(self.__4Events4PerP,f)
with open('2.json', 'w', encoding='utf-8') as f:
json.dump(self.__4Events4PerR,f)
with open('3.json', 'w', encoding='utf-8') as f:
json.dump(self.__4Events4PerPPerR,f)
def __parseDict(self, d: dict, prefix: str):
_d = {}
for k in d.keys():
if str(type(d[k]))[-6:-2] == 'dict':
_d.update(self.__parseDict(d[k], k))
else:
_k = f'{prefix}__{k}' if prefix != '' else k
_d[_k] = d[k]
return _d
def __listOfNestedDict2ListOfDict(self, a: list):
records = []
for d in a:
_d = self.__parseDict(d, '')
records.append(_d)
return records
def getEventsUsers(self, username: str, event: str) -> int:
if not self.__4Events4PerP.get(username,0):
return 0
else:
return self.__4Events4PerP[username].get(event,0)
def getEventsRepos(self, reponame: str, event: str) -> int:
if not self.__4Events4PerR.get(reponame,0):
return 0
else:
return self.__4Events4PerR[reponame].get(event,0)
def getEventsUsersAndRepos(self, username: str, reponame: str, event: str) -> int:
if not self.__4Events4PerP.get(username,0):
return 0
elif not self.__4Events4PerPPerR[username].get(reponame,0):
return 0
else:
return self.__4Events4PerPPerR[username][reponame].get(event,0)
class Run:
def __init__(self):
self.parser = argparse.ArgumentParser()
self.data = None
self.argInit()
print(self.analyse())
def argInit(self):
self.parser.add_argument('-i', '--init')
self.parser.add_argument('-u', '--user')
self.parser.add_argument('-r', '--repo')
self.parser.add_argument('-e', '--event')
def analyse(self):
if self.parser.parse_args().init:
self.data = Data(self.parser.parse_args().init, 1)
return 0
else:
if self.data is None:
self.data = Data()
if self.parser.parse_args().event:
if self.parser.parse_args().user:
if self.parser.parse_args().repo:
res = self.data.getEventsUsersAndRepos(
self.parser.parse_args().user, self.parser.parse_args().repo, self.parser.parse_args().event)
else:
res = self.data.getEventsUsers(
self.parser.parse_args().user, self.parser.parse_args().event)
elif self.parser.parse_args().repo:
res = self.data.getEventsRepos(
self.parser.parse_args().reop, self.parser.parse_args().event)
else:
raise RuntimeError('error: argument -l or -c are required')
else:
raise RuntimeError('error: argument -e is required')
return res
if __name__ == '__main__':
a = Run()
提交: 109 人,未提交: 17 人
未提交名单: 后来喵 披风风 kexiaoke DoGoods htx1 殤-l Double-Ten 冲就完了 第一组 网益云 栋哥说的都队 2020软工-八级大狂风 冬天的冰淇淋不会化 军舰队 呜呼啦呼队 栋的都懂 以上队伍成绩无效队