第一次个人编程作业

❄github链接

仓库地址

以上是在github创建的仓库,里面是我的学号.py文件

❄PSP表格

PSP2.1Personnal Software
Process Stagese
预估耗时
(分钟)
实际耗时
(分钟)
Planning计划2020
* Estimate* 估计这个任务需要多少时间480540
Development开发180300
* Analysis* 需求分析(包括学习新技术)300240
* Design Spec* 生成设计文档120120
* Design Review* 设计复审9060
* Coding Standard* 代码规范(为目前的开发制定合适的规范)3030
* Design* 具体设计120100
* Coding* 具体编码200180
* Test* 测试(自我测试,修改代码,提交修改)100120
Reporting报告8090
* Test Repor* 测试报告5060
* Size Measurement* 计算工作量3030
* Postmortem & Process
Improvement Plan
* 事后总结,并提出过程改进计划6090
 * 合计18601980

❄计算模块接口的设计与实现过程

知识点

  • 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]):把地址分割为五级地址

        流程图

        1797752-20190929191353098-1578244681.png

        主要代码

  • 分割出难度等级和电话号码
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的性能分析

    1797752-20190929191414758-1166856244.png
  • ncalls:表示函数调用的次数;
  • tottime:表示指定函数的总的运行时间,除掉函数中调用子函数的运行时间;
  • percall:(第一个 percall)等于 tottime/ncalls;
  • cumtime:表示该函数及其所有子函数的调用运行的时间,即函数开始调用到返回的时间;
  • percall:(第二个 percall)即函数运行一次的平均时间,等于 cumtime/ncalls;
  • filename:lineno(function):每个函数调用的具体信息;

    这是用vs studio2017的性能探查器的性能分析

    1797752-20190929191425983-1306823608.png

    ❄计算模块部分单元测试展示

    单元测试

  • 输入
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,最后是把全部的例子复制黏贴到运行得出了覆盖率。
    1797752-20190929191440564-902363004.png

    ❄计算模块部分异常处理说明

    • 必须把直辖市:北京、天津、重庆、上海的前三级地址区分来写,否则会出现错误
      例如:
      输入:
      2!单轿组,上海市浦东新区洋泾街道博山路12号泾东新15155759742村.
      输出:
      {"姓名": "单轿组", "手机": "15155759742", "地址": ["", "", "", "上海市浦东新区洋泾街道", "博山路", "12号", "泾东新村"]}
    • 五级地址分割的时候,应注意出现“街道”的情况,七级地址分割的时候应注意,查询到号的时候要判断一下后面是否为楼,如果为楼,则第六级地址为空
    • 如果遇到姓名或者电话号码为空的情况下,应该设置一个函数当循环变量大于字符串长度时退出循环,并将姓名或者电话设为空。

      ❄心得体会

  • 首先是了解了更多关于python的使用方法,我认为这个是很受用的。
  • 在编程过程中锻炼了自己根据关键词搜索相应知识点的能力。
  • 不管是编程还是后续的优化都存在不足,一开始编程的时候一根筋地只弄一个函数,我真是太后悔了,反正后来花了一点时间改一下,代码变整洁不少,这个经验也很重要。

转载于:https://www.cnblogs.com/bbbr/p/11609543.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值