2021秋软工实践第一次个人编程作业
这个作业属于哪个课程 | 构建之法-2021秋-福州大学软件工程 |
---|---|
这个作业要求在哪里 | 2021秋软工实践第一次个人编程作业 |
这个作业的目标 | 学习使用GitHub、制定代码规范、完成C/C++文件的关键字提取 |
学号 | 031904138 |
制定个人代码规范
个人GitHub主页
文章目录
- 一、PSP表格
- 二、解题思路描述
- 三、设计实现过程
- 四、代码说明
- 五、单元测试与性能分析
- 六、总结
一、PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 60 | 60 |
Estimate | 估计这个任务需要多少时间 | 30 | 20 |
Development | 开发 | 300 | 360 |
Analysis | 需求分析 (包括学习新技术) | 30 | 45 |
Design Spec | 生成设计文档 | 30 | 60 |
Design Review | 设计复审 (和同事审核设计文档) | 30 | 30 |
Coding Standard | 代码规范 (为目前的开发制定合适的规范 | 60 | 90 |
Design | 具体设计 | 60 | 100 |
Coding | 具体编码 | 500 | 720 |
Code Review | 代码复审 | 60 | 60 |
Test | 测试(自我测试,修改代码,提交修改) | 180 | 200 |
Reporting | 报告 | 150 | 180 |
Test Report | 测试报告 | 60 | 80 |
Size Measurement | 计算工作量 | 30 | 30 |
Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 | 60 | 80 |
合计 | 1640 | 2115 |
二、解题思路描述
基础要求:输出关键字统计信息
(1)读入代码文件,过滤掉空行、非字母的字符,同时删除文件中的注释等部分
(2)使用.split()方法对文本进行切片,将文本分割为单词列表WordList
(3)遍历列表WordList,得到列表中的关键字统计信息进阶要求:输出有几组switch case结构,同时输出每组对应的case个数
(1)遍历基础要求中得到的WordList[ ],得到全部的switch和case,按顺序记录在另一个列表switch_case中
(2)遍历列表switch_case,得到switch数目以及对应的case数目拔高要求:输出有几组if else结构
记得当时上数据结构时写过一道括号配对的题,寻思着if-else配对和括号配对应该是一类问题,采用的数据结构是栈,本来打算用stack来做,但是为了方便遍历,就换成了列表的形式+堆栈的思路
终极要求:输出有几组if,else if,else结构
思路同上
三、设计实现过程
- 先定义需要的关键函数:
def split_word(dir) # 用于把对应路径的文件分词成列表
def merge_if_else(list) # 用于合并列表中配对的if和else
def merge_if_elseif_else(list) #用于合并列表中配对的if-elseif-else
def count_key(dir,rank) # 实现统计关键字功能
- 以上关键函数的流程图:
1、split_word(dir):将代码文件中的全部单词分词为一个列表
2、merge_if_else(list):合并列表中配对的if和else
以文件样例为例:
3、merge_if_elseif_else(list):合并列表中配对的if-elseif-else
连续的else-if都视作一个if-elseif-else结构,因此只要存在连续的if-else就将其更新为一个"if-elseif-else"字符串
4、count_key(dir,rank):实现统计关键字功能
四、代码说明
本次代码中有四个关键函数,详细思路如设计实现过程中流程图所示
1、split_word(dir):将代码文件中的全部单词分词为一个列表
#把文件内的单词分割为列表
def split_word(dir): #dir为输入的代码文件路径f = open(dir, 'r', encoding='gbk')lines = f.readlines() new_line="" # 用于记录文件内容的字符串for line in lines: # 逐行读入代码文件if line != '' and line != '\n': # 过滤空行new_line = new_line + line # 把文件内容连接成一个字符串new_line = remove(new_line) # 去除注释部分以及引号的内容new_line = remove_non_letter(new_line) # 去除非字母部分new_line = new_line.strip() # 去除前后空格lis = new_line.split(" ") # 分割成列表lis = del_empty(lis) # 删除列表中空值return lis
2、merge_if_else(list):合并列表中配对的if和else
# 把if和对应else进行配对
def merge_if_else(list):if_else=[] # 记录if-else结构的列表if_else.append(list[0]) # 把if_else列表当成栈使用for word in list[1:]: # 把else与其配对的if连接起来if word=="else":if if_else[-1]=="if":if_else.pop()if_else.append("if-else")else:if_else.append(word)else:if_else.append(word)return if_else
3、merge_if_elseif_else(list):合并列表中配对的if-elseif-else
# 把if-elseif-else进行配对
def merge_if_elseif_else(list):if_elseif_else = [] # 记录if-elseif_else结构的列表if_elseif_else.append(list[0]) # 把if_elseif_else列表当成栈使用for word in list[1:]: # 把if_else与if_else连接起来if word == "if-else" and if_elseif_else[-1] != "if" and if_elseif_else[-1] != "else":if_elseif_else.pop()if_elseif_else.append("if-elseif-else")else:if_elseif_else.append(word)# print(if_elseif_else)return if_elseif_else
4、count_key(dir,rank):实现统计关键字功能
在此函数分别设置里实现不同需求的函数,分别是:
def rank_1() # rank1基础要求:输出关键字统计信息def rank_2() # rank2进阶要求:输出有几组switch case结构,同时输出每组对应的case个数def rank_3() # rank3:拔高要求:输出有几组if-else结构def rank_4() # rank4:终极要求:输出有几组if-elseif-else结构
各需求的具体代码如下:
# rank1基础要求:输出关键字统计信息def rank_1(): for word in word_list:if word in keyWords: # 提取出关键字并存放到 keyword_list[ ]中keyword_list.append(word)continueprint("total num: {0}".format(len(keyword_list)))
# rank2进阶要求:输出有几组switch case结构,同时输出每组对应的case个数def rank_2():switch_case=[] #用于记录按序取出的所有switch,casefor word in word_list:if word in ['switch','case']: #提取出switch,case并存放到switch_case[ ]中switch_case.append(word)switch_num = 0 # 记录switch的数目case_num = [] # 记录case的数目for i in range(len(switch_case)): # 遍历列表得到全部switch-case结构if switch_case[i] == "switch":switch_num += 1temp_case_num = 0for j in range(i+1,len(switch_case)):if switch_case[j] == "case":temp_case_num += 1else:breakcase_num.append(temp_case_num)#控制输出格式print("switch num: {0}".format(switch_num))if (len(case_num) == 0):print("case num: 0")else:print("case num: ", end='')for num in case_num:print(str(num) + " ", end='')print()
#rank3:拔高要求:输出有几组if-else结构def rank_3():ifOrElse = [] # 记录所有单个if,else的列表if_else_num=0 # 记录if-else的数量for word in word_list:if word=="if" or word=="else":ifOrElse.append(word) # 把所有的if else单独提取出来if_else = merge_if_else(ifOrElse) # 逐步进行合并 先配对if-elseif_elseif_else = merge_if_elseif_else(if_else) #再配对if-elseif-elseif(len(if_elseif_else)!=0):while("if-elseif-else" in if_elseif_else): # 统计if-elseif-else数目for i in range(len(if_elseif_else)):if if_elseif_else[i]=="if-elseif-else":if_elseif_else[i]="" #记录完后删除if_elseif_else=del_empty(if_elseif_else) # 删除列表中的空值if(len(if_elseif_else)!=0):if_else=merge_if_else(if_elseif_else) #再次进行合并if_elseif_else=merge_if_elseif_else(if_else)if(len(if_elseif_else)!=0):if_else = merge_if_else(if_elseif_else) #对统计完if-elseif-else的列表进行合并while ("if-else" in if_else): # 统计if-else的数目for i in range(len(if_else)):if if_else[i] == "if-else":if_else[i] = "" # 统计完后删除if_else_num += 1if_else = del_empty(if_else) # 删除列表中的空值if(len(if_else)!=0):if_else = merge_if_else(if_else) # 再次进行合并print("if-else num: {0}".format(if_else_num)) # if-else的数目
终极要求在rank3中已经实现了,步骤同上,此处就不再赘述
因此,count_key(dir,rank)的总结构表示如下:
def count_key(dir,rank):if rank==1:rank_1()if rank==2:rank_1()rank_2()if rank==3:rank_1()rank_2()rank_3()if rank==4:rank_1()rank_2()rank_3()rank_4()
五、单元测试与性能分析
1、使用C语言文件样例进行测试,运行结果:
2、使用coverage工具统计python单元测试覆盖率
执行代码覆盖率统计,只需要通过coverage的run参数执行被统计代码即可,命令行输入:
coverage run test.py arg1 arg2
会自动生成一个覆盖率统计结果文件(data file):.coverage。
有了覆盖率统计结果文件,只需要再运行report参数,就可以在命令里看到统计的结果
命令行输入:
coverage report
Stmts/Miss表示语句总数/未执行到的语句数
3、性能分析
由于程序运行时间有点短,加入了time.sleep(10)再进行性能分析
按照累积时间进行降序排序并输出
其中,输出每列的具体解释如下:
ncalls:表示函数调用的次数;
tottime:表示指定函数的总的运行时间,除掉函数中调用子函数的运行时间;
percall:(第一个percall)等于 tottime/ncalls;
cumtime:表示该函数及其所有子函数的调用运行的时间,即函数开始调用到返回的时间;
percall:(第二个percall)即函数运行一次的平均时间,等于 cumtime/ncalls;
filename:lineno(function):每个函数调用的具体信息;
从图中得到的信息为:
1、整个过程一共有1965个函数调用被监控,其中1913个是原生调用(即不涉及递归调用)
2、总共执行的时间为22.961秒(包括一个time.sleep(10))
3、可见程序大部分时间主要花在分离不同需求关键字的过程中,其中把代码文件拆分为单词列表的过程是一个主要耗时的部分。
六、总结
- 通过此次个人编程作业,接触到了PSP表格,第一次深入了解了github的具体使用,更加熟悉了使用MarkDown进行博客的排版编写,了解到更多python的编码规范,也对逐步完成需求有了初步的认识。
- 遇到很多没接触过的词汇,单元测试,性能分析,单元测试覆盖率…面向百度查阅了好多好多资料,过程繁杂但也收获满满,get了一些新技能比如GitHub的使用,正则表达式的使用,单元测试工具的使用等等
- 在此过程中也认识到自己有很多的不足,代码都是很基础的语法,不够简洁,没有选择到效率更高的数据结构,总体上还是感觉差强人意,希望这些过程能够成为激励自己的动力吧,边学边做边积累,加油加油加油!
附1:完整代码
countKey.py
附2:GitHub Commit截图
2021秋软工实践第一次个人编程作业相关推荐
- 2021秋软工实践第一次结对编程作业
这个作业属于哪个课程 构建之法-2021秋-福州大学软件工程 这个作业要求在哪里 2021秋软工实践第一次结对编程作业 这个作业的目标 实现博饼软件原型并进行博客写作 学号 031902139 队友学 ...
- 2021秋软工实践第一次结对编程作业-需求分析
博饼软件需求分析 一.简要说明 博饼,是厦门人几百年来独有的中秋传统活动,是一种独特的月饼文化,也是厦门人对历史的一种传承.现在,博饼依然是厦门人最钟爱的中秋活动,也是最热闹的一个民俗节日形式. 目前 ...
- 2022秋软工实践 第一次结对编程作业
2022秋软工实践 第一次结对编程作业 需求分析 (1)Need,需求 (2)Approach,做法 (3)Benfit,好处 (4)Competitors,竞争 (5)Delivery,推广 UML ...
- 2021秋软工实践个人作业一
2021秋软工实践个人作业一 2021秋软工实践个人作业一 自我介绍 技能树 精简技能树 技能树描述 学期目标 软件工程A 构建之法-2021秋-福州大学软件工程 作业要求 2021秋软工实践个人作业 ...
- 2021秋软工实践 Lab6 团队展示与选题报告
作业所属课程 构建之法-2021秋-福州大学软件工程 作业要求 第6次作业-团队展示+选题报告 作业的目标 为开源爱好者服务,实现更实用.更便利.更具人性化的GitHub工具类小程序 团队名称 MDY ...
- 软工实践第一次博客作业
1.个人简介 我是031702109唐怡:爱好是听歌,火漆:在福大食堂最喜欢的就是西红柿炒鸡蛋:最近超迷<all time low(cash cash remix)>:听闻先生治家有方,鄙 ...
- 软工实践第一次作业-自我审视和规划
软工实践第一次作业-自我审视和规划 题目地址:https://edu.cnblogs.com/campus/fzu/FZUSoftwareEngineering1816W/homework/2060? ...
- 软工实践第一次作业-准备
软工实践第一次作业-准备 标签(空格分隔): 软工实践 Chs97's Blog 回想一下你初入大学时对计算机专业的畅想 当初你是如何做出选择计算机专业的决定的? 计算机或许是注定的吧.回想第一次接触 ...
- 2022秋软工实践个人作业二
2022秋软工实践个人作业二 Task I Task II 这个作业属于哪个课程 软工实践 这个作业要求在哪里 2022秋软工实践个人作业二 这个作业的目标 git html 学号 032002342 ...
- 软工实践第八次作业(软件工程实践总结)
原博客 目录 一.请回望暑假时的第一次作业,你对于软件工程课程的想象 二.个人或结对或团队项目实践中的经验总结+实例/例证结合的分析 三.对下一届实践的建议和告知.对于后来人的期许. 四.分析一下自己 ...
最新文章
- Matlab和Modelsim联合仿真的配置
- java点到原点距离_java-从经纬度坐标到欧氏距离(EuclideanDistance)完整代码
- android git上传出现错误,热更新上传patch包时提示上传失败,文件不合法
- ClassCastException:AdaptiveIconDrawable cannot be cast to BitmapDrawable
- Express 路由、Ejs 、静态文件托管、中间件
- linux resin 查看日志命令,【转】linux:访问日志分析
- mysql 分页拦截器_MyBatis 拦截器 (实现分页功能)
- Makefile的学习笔记
- HD 2177(威佐夫博弈 入门)
- 60天申请软件著作权
- 20211104 为什么相似矩阵的迹相同
- 我的python笔记06
- 爬取网站小猪短租的少量信息及详细介绍 ,requests库,bs4库的使用
- 接口耗时优化与cpu飙高解决
- qr码生成_在PHP中生成QR码
- fiilt1左耳连不上_FIIL T1完美解决真无线耳机的痛点:更快更稳更自由
- NYOJ-20 吝啬的国度 AC
- nth_element(C++)
- 【源码分享】ASP.NET企业办公综合管理系统源码(OA+CRM+进销存+财务)
- Linguistic Sorting and Matching
热门文章
- 杭州治堵有“智慧” 阿里云数加激活城市大脑
- java中怎样显示图片_[Java教程]Java中显示图片的方法
- 基于CNN的区域特定多尺度特征提取的两阶段停车位检测
- 2007福布斯名人榜完全名单 巩俐收入盖过章子怡
- 1090: 哥德巴赫猜测
- 【论文笔记】Switching Convolutional Neural Network for Crowd Counting
- 企业怎样优化用户体验?F5给出三条专业建议
- 恶魔和梦魇的私语------- 关于软件开发的务虚主义对话(3)
- 区块链交易验证和支付验证
- 解决了Office2007向程序发送命令时出现错误 的问题