第一次个人编程作业

Github链接

PSP表格

||||||||||||||
|:--😐:--😐:--😐:--😐
|PSP2.1|Personal Software Process Stages|预估耗时(分钟)|实际耗时(分钟)|
|Planning|计划|60|80|
|Estimate|估计这个任务需要多少时间|20|30|
|Development|开发|300|400|
|Analysis|需求分析 (包括学习新技术)|300|400|
|Design Spec|生成设计文档|45|60|
|Design Review|设计复审|20|25|
|Coding Standard|代码规范 (为目前的开发制定合适的规范)|20|25|
|Design|具体设计|120|130|
|Coding|具体编码|400|450|
|Code Review|代码复审|30|40|
|Test|测试(自我测试,修改代码,提交修改)|200|250|
|Reporting|报告|120|150|
|Test Repor|测试报告|100|100|
|Size Measurement|计算工作量|30|45|
|Postmortem & Process Improvement Plan|事后总结, 并提出过程改进计划|30|40|
||合计|1795|2225|

解题思路

   刚开始看到题目的时候,发现这好像和快把隔壁班搞疯的题目一样,瞬间懵了,内心无比拒绝。但还是很快静下心来,仔细看了两遍题目后,首先感觉这本质上就是字符串处理的问题,只是这道题要处理中文比较麻烦。本来想用C++写,至少这个相比Java和Python更熟悉一些,但根据刚做过这道题的同学的经验,C++挺难写的,最后还是决定用Python写。就这样开始了边自学Python边开始打代码的艰苦历程。

用Python编程的思路:

  • 先判断输入的字符串属于几级难度。
  • 用正则表达式提取姓名和手机号码,去除字符串末尾的句号。
  • 从省级行政区开始一级一级匹配,四个直辖市特殊处理。
  • 一级难度只需分离到五级地址,二级难度分离到七级地址,由于时间紧迫加上自己太菜了,三级难度我直接Pass掉了。
  • 有很多特殊情况需要特殊考虑。

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

代码组织:

   主函数中输入字符串,首先判断为几级难度,然后提取姓名,手机号码,每一次提取都要把提取的部分从原字符串删除,接下来就是通过调用函数来提取各级地址,最后转换为json格式输出。可以写一个addressbook类,但由于对Python的类掌握不够,导致使用类的时候一直报错,出现了一些我暂时无法处理的Bug,纠结的卡了很久,最后的结果代码还是没有用到类。

主要函数:

||||||
|:--😐:--😐
|def get_province(string)|提取省级地址|
def get_city(string)|提取市级地址
def get_county(string)|提取县级地址
def get_town(string)|提取乡镇级地址
def get_road(string)|提取路名地址
def get_doornum(string)|提取门牌号

主要程序的流程图:

算法的关键和独到之处

  • 算法的关键:

     关键在于函数的组织和调用,在用正则表达式处理字符串时,还有一些特殊情况的完整考虑。
    
  • 独到之处:

     引入了两个列表,分别是全国所有的市级地址和所有的区级地址,而不是单纯的处理字符串(会漏掉很多特殊情况),也不是把全国的所有行政地址全部导入。
    

模块接口部分的性能改进

  • 改进思路:

      初步完成的代码仅仅是通过分离字符串,发现这样只能处理一部分的情况,通过百度中国地图行政级别划分,补充了很多特殊情况的考虑,但一些更特殊的只能通过引入字典或列表实现,虽然这样会让代码变得很长,但实现功能才是最重要的。
    
  • 性能分析图如下(使用VS自带的Python分析器得到):

  • 消耗最大的函数:
def get_county(string):            #获得县
    str=re.search("(.*?自治旗)|(.*?[县区市旗])",string)
    if str==None:
        for i in areas:
            if string[0:2] in i:
                return i
        return ""
    return str.group()

模块部分单元测试展示

Input:

1!明啥,海南海口市龙华区金宇街道坡博西村59-1号坡港湾网13041699300吧.
1!钦瓷逆,上海奉贤区金海社区龙潭15068988920村老人活动中心.
1!宫焊,上海市虹15038265133桥街道中山西路1065号中山广场B座.
1!宁枪裂,北京市平谷区滨河街道林荫北路7号金谷东园7号楼18883080553.
1!印模,云南省红河哈尼族彝族自治州蒙自市明白村明白小15153379393学.
1!殴删谭,河北承德承15076364360德县岗子满族乡253省道齐家营中心幼儿园.
2!蒋套汞,上海市松江区岳阳街道中13454083467山二路32弄北龙潭.
2!解维牌,上海市长宁区13345422905仙霞新村街道虹古路261弄虹古小区4号楼.
2!夹谷抡枯,18795320124甘肃省兰州城关区皋兰路街道皋兰路210号郑家台小区.
2!羊舌线,福建省福州鼓楼区鼓东街13827706785道庆城路庆城社区.

Output:

  {"姓名":"明啥","手机":"13041699300","地址":["海南省","海口市","龙华区","金宇街道","坡博西村59-1号坡港湾网吧"]}
  {"姓名":"钦瓷逆","手机":"15068988920","地址":["上海","上海市","奉贤区","金海社区","龙潭村老人活动中心"]}
  {"姓名":"宫焊","手机":"15038265133","地址":["上海","上海市","","虹桥街道","中山西路1065号中山广场B座"]}
  {"姓名":"宁枪裂","手机":"18883080553","地址":["北京","北京市","平谷区","滨河街道","林荫北路7号金谷东园7号楼"]}
  {"姓名": "印模", "手机": "15153379393", "地址": ["云南省", "红河哈尼族彝族自治州", "蒙自市", "", "红河哈尼族彝族自治州蒙自市明白村明白小学"]}
  {"姓名": "殴删谭", "手机": "15076364360", "地址": ["河北省", "承德市", "承德县", "岗子满族乡", "253省道齐家营中心幼儿园"]}
  {"姓名":"蒋套汞","手机":"13454083467"},"地址":["上海","上海市","松江区","岳阳街道","中山二路","32弄","北龙潭"]}
  {"姓名":"解维牌","手机":"13345422905","地址":["上海","上海市","长宁区","仙霞新村街道","虹古路","261弄","虹古小区4号楼"]}
  {"姓名": "夹谷抡枯", "手机": "18795320124", "地址": ["甘肃省", "兰州市", "城关区", "皋兰路街道", "皋兰路", "210号", "郑家台小区"]}
  {"姓名": "羊舌线", "手机": "13827706785", "地址": ["福建省", "福州市", "鼓楼区", "鼓东街道", "庆城路", "", "庆城社区"]}

测试代码覆盖率

模块部分异常处理说明

    输入字符串“2!小美,北京市东15822153326城区交道口东大街1号北京市东城区人民法院.”时,输出{"姓名": "小美", "手机": "15822153326", "地址": ["北京", "北京市", "东城区", "","交道", "口东大街1号", "北京市东城区人民法院"]},错误的将交道口东大街分离。
    输入字符串“1!家基,江苏省18828767011连云港赣榆区海头镇赣柘线盐仓城村村委会.”时,输出{"姓名": "家基", "手机": "18828767011", "地址": ["江苏省", "连云市", "港赣榆区", "海头镇", "赣柘线盐仓城村村委会"]},连云港市提取错误。

心路历程与收获

    在短短的一周时间内,硬逼着自己学了很多东西,接触了很多没接触过的东西,从最开始的手足无措,到静下心来一步一步解决遇到的问题,查百度,看博客,问大佬,慢慢学习,虽然过程很痛苦,但还是值得的,也让我深刻的意识到,自己真的很菜很菜,要学的还有很多很多,最重要的还是心态,一定要不骄不躁才能写好代码,接下来我一定会不断地提升自己的编程实践能力,毕竟未来的路还长,要学的还很多,不试着逼自己一把,怎么知道自己有多大的潜力。(不过长时间这样的话头发可能会掉光,还是要适当劳逸结合吧)
posted @ 2019-09-29 20:22  不知足?  阅读(205)  评论(1编辑  收藏  举报