• 福州大学软件工程实践个人编程作业


    这个作业属于哪个课程 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())
    

    单元测试

    单元测试覆盖率优化

    性能优化

    正则表达式的匹配优化
    对于冗余数据的不处理

    代码规范链接

    代码规范点这里

    总结

    这次的作业对于我而言,是非常难的,平时码的都是算法题,
    没有任何开发经验,从最开始有点无从下手,慢慢摸索直至
    走上正轨。学习的过程中可以多多询问他人,这样事半功倍。
    这次的作业让我明白,还有很多的东西要学,目前的知识还
    是太匮乏了。

  • 相关阅读:
    算法5--排序
    算法4---数组
    算法3---字符串
    算法2---链表4---单循环链表
    wcf精通1-15
    框架技术细节
    Achieving High Availability and Scalability
    Windows平台下利用APM来做负载均衡方案
    Windows平台分布式架构实践
    web api control注册及重写DefaultHttpControllerSelector、ApiControllerActionSelector、ApiControllerActionInvoker
  • 原文地址:https://www.cnblogs.com/FZUlh/p/13682051.html
Copyright © 2020-2023  润新知