❄github链接
以上是在github创建的仓库,里面是我的学号.py文件
❄PSP表格
PSP2.1 | Personnal Software Process Stagese | 预估耗时 (分钟) | 实际耗时 (分钟) | |
---|---|---|---|---|
Planning | 计划 | 20 | 20 | |
* Estimate | * 估计这个任务需要多少时间 | 480 | 540 | |
Development | 开发 | 180 | 300 | |
* Analysis | * 需求分析(包括学习新技术) | 300 | 240 | |
* Design Spec | * 生成设计文档 | 120 | 120 | |
* Design Review | * 设计复审 | 90 | 60 | |
* Coding Standard | * 代码规范(为目前的开发制定合适的规范) | 30 | 30 | |
* Design | * 具体设计 | 120 | 100 | |
* Coding | * 具体编码 | 200 | 180 | |
* Test | * 测试(自我测试,修改代码,提交修改) | 100 | 120 | |
Reporting | 报告 | 80 | 90 | |
* Test Repor | * 测试报告 | 50 | 60 | |
* Size Measurement | * 计算工作量 | 30 | 30 | |
* Postmortem & Process Improvement Plan | * 事后总结,并提出过程改进计划 | 60 | 90 | |
* 合计 | 1860 | 1980 |
❄计算模块接口的设计与实现过程
知识点
- python 语法
- cpca:
- 一个用于提取简体中文字符串中省,市和区并能够进行映射,检验和简单绘图的Python模块
- cpca的github地址
正则表达式
设计
- 思路
- 前人的血泪史告诉我不该用c++编程,于是花了半天学习了Python的语法,讲道理只是看是没有用的,毕竟只是囫囵吞枣,所以在实现过程中也是疯狂百度函数的具体使用
- 五级地址和七级地址的实现过程是有重合的地方的,所以在实现分割七级地址的时候调用五级地址的函数之后,再进行分割就好了
- 分割难度等级、姓名的时候,都可以用split()函数,分别用“!”和“,”进行分割
- 分割电话号码首先要用正则表达式将字符串中的数字串筛选出来,然后根据数字串的位数判断哪个是电话号码
- 利用cpca库将纯地址分割成四级地址,再利用关键字查询分割成五级地址
- 分割七级地址的后三个地址也是利用关键词查询分割
- 函数
- def five(arr):分割五级地址
- arr.split(",")[0]:分割出姓名
- re.findall(r'\d+',arr):筛选出数字序列,之后再根据位数进行筛选
- cpca.transform(list):把地址分割成四级地址
- def seven(arr):分割七级地址
five(x[1]):把地址分割为五级地址
流程图
主要代码
- def five(arr):分割五级地址
- 分割出难度等级和电话号码
x=arr.split("!")/*其中x[0]为难度等级*/
arr=arr[:(len(arr)-1)]
d["姓名"]=arr.split(",")[0]/*分割出姓名*/
- 分割出电话号码
df=re.findall(r'\d+',arr)/*正则表达式*/
i=0
while(1):
if(i>=len(df)):
break
elif(len(df[i])==11):
d['手机']=df[i]
break
else:
i=i+1
- 分割出四级地址
list=[arr]
list=cpca.transform(list)/*cpca库*/
arr=np.array(list)
addr[0]=arr[0][0]
addr[1]=arr[0][1]
addr[2]=arr[0][2]
arr=arr[0][3]
- 分割出五级地址
i=0
while 1:
if i>=len(arr):
addr[3]=''
addr[4]=arr
break
elif(arr[i]=="街" and arr[i+1]=="道"):
addr[3]=arr[:i+2]
addr[4]=arr[i+2:]
break
elif(arr[i]=="镇"):
addr[3]=arr[:i+1]
addr[4]=arr[i+1:]
break
elif(arr[i]=="乡"):
addr[3]=arr[:i+1]
addr[4]=arr[i+1:]
break
elif(arr[i]=="街" and arr[i+1]!="镇" and arr[i+1]!="乡" and arr[i+1].isdigit()==False ):
addr[3]=arr[:i+1]
addr[4]=arr[i+1:]
break
else:
i=i+1
- 直辖市前三级地址的特殊处理
if arr[:2]=='北京' or arr[:2]=='上海' or arr[:2]=='天津' or arr[:2]=='重庆':
addr[0]=arr[:2]
if arr[2]!='市':
addr[1]=arr[:2]+'市'
arr=arr[2:]
else:
addr[1]=arr[:3]
arr=arr[3:]
i=0
while 1:
if i>=len(arr):
addr[2]=''
break
elif(arr[i]=="区" or arr[i]=="县" or arr[i]=="市"):
addr[2]=arr[:i+1]
arr=arr[i+1:]
break
else:
i=i+1
- 分割出七级地址中的后三级
i=0
while 1:
if(i>=len(arr)):
break
elif arr[i]=='道' or arr[i]=='路' or arr[i]=='街' or arr[i]=='巷':
addr[4]=arr[:i+1]
arr=arr[i+1:]
break
else:
i=i+1
i=0
while 1:
if(i>=len(arr)):
break;
elif arr[i]=='号':
addr[5]=arr[:i+1]
addr[6]=arr[i+1:]
break
else:
i=i+1
算法的关键与独到之处
算法的关键处是要学会用python的函数,功能都很方便,比如split(),也要会用cpca、正则表达式等知识。
❄计算模块接口部分的性能改进
性能分析
这是用python自带的库profile的性能分析
- ncalls:表示函数调用的次数;
- tottime:表示指定函数的总的运行时间,除掉函数中调用子函数的运行时间;
- percall:(第一个 percall)等于 tottime/ncalls;
- cumtime:表示该函数及其所有子函数的调用运行的时间,即函数开始调用到返回的时间;
- percall:(第二个 percall)即函数运行一次的平均时间,等于 cumtime/ncalls;
filename:lineno(function):每个函数调用的具体信息;
这是用vs studio2017的性能探查器的性能分析
❄计算模块部分单元测试展示
单元测试
- 输入
1!皇甫享,安徽宣城郎13734164891溪县飞鲤镇011乡道西三立村村委会.
1!家按犯,西藏自治区昌都卡若区城关镇214国道城关镇嘎东街社区居民委员15347650776会.
2!季宋,湖北咸宁市崇阳县肖岭乡下隽街中共肖岭村支15164791535部委员会.
2!咸黄薇,广东省汕尾城区新港街道汕尾13701884806大道海港城6栋.
2!谯歇殊,北京东城区18913638130东直门街道香河园北里小区5号楼.
- 输出
{"姓名": "皇甫享", "手机": "13734164891", "地址": ["安徽省", "宣城市", "郎溪县", "飞鲤镇", "011乡道西三立村村委会"]}
{"姓名": "家按犯", "手机": "15347650776", "地址": ["西藏自治区", "昌都市", "卡若区", "城关镇", "214国道城关镇嘎东街社区居民委员会"]}
{"姓名": "季宋", "手机": "15164791535", "地址": ["湖北省", "咸宁市", "崇阳县", "肖岭乡", "下隽街", "", "中共肖岭村支部委员会"]}
{"姓名": "咸黄薇", "手机": "13701884806", "地址": ["广东省", "汕尾市", "城区", "新港街道", "汕尾大道", "", "海港城6栋"]}
{"姓名": "谯歇殊", "手机": "18913638130", "地址": ["北京", "北京市", "东城区", "东直门街道", "", "", "香河园北里小区5号楼"]}
覆盖率
利用python自带的工具Coverage统计代码的覆盖率,不是很明白怎么用unittest,最后是把全部的例子复制黏贴到运行得出了覆盖率。
❄计算模块部分异常处理说明
- 必须把直辖市:北京、天津、重庆、上海的前三级地址区分来写,否则会出现错误
例如:
输入:2!单轿组,上海市浦东新区洋泾街道博山路12号泾东新15155759742村.
输出:{"姓名": "单轿组", "手机": "15155759742", "地址": ["", "", "", "上海市浦东新区洋泾街道", "博山路", "12号", "泾东新村"]}
- 五级地址分割的时候,应注意出现“街道”的情况,七级地址分割的时候应注意,查询到号的时候要判断一下后面是否为楼,如果为楼,则第六级地址为空
如果遇到姓名或者电话号码为空的情况下,应该设置一个函数当循环变量大于字符串长度时退出循环,并将姓名或者电话设为空。
❄心得体会
- 必须把直辖市:北京、天津、重庆、上海的前三级地址区分来写,否则会出现错误
- 首先是了解了更多关于python的使用方法,我认为这个是很受用的。
- 在编程过程中锻炼了自己根据关键词搜索相应知识点的能力。
不管是编程还是后续的优化都存在不足,一开始编程的时候一根筋地只弄一个函数,我真是太后悔了,反正后来花了一点时间改一下,代码变整洁不少,这个经验也很重要。