zoukankan      html  css  js  c++  java
  • 第一次个人编程作业

    第一次个人编程作业Github地址

    PSP表格

    PSP2.1 Personal Software Process Stages 预估耗时(min) 实际耗时(min)
    Planning 计划 15 30
    Estimate 估计这个任务需要多少时间 900 1200
    Development 开发 810 1100
    Analysis 需求分析 (包括学习新技术) 100 100
    Design Spec 生成设计文档 80 50
    Design Review 设计复审 10 10
    Coding Standard 代码规范 (为开发制定合适的规范) 20 20
    Design 具体设计 100 120
    Coding 具体编码 400 600
    Code Review 代码复审 50 50
    Test 测试 (自我测试,修改,提交修改) 50 150
    Reporting 报告 90 100
    Test Report 测试报告 50 60
    Size Measurement 计算工作量 10 10
    Postmortem & Process Improvement Plan 事后总结 并提出过程改进计划 30 30
    合计 915 1230

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

    解题步骤and心路历程

    • 先对输入的字符串进行简单的处理,提取出难度等级、姓名、手机号和总的地址串

      刚看到题目的时候全懵了,这个字符串要这么切分啊,完全不懂。然后我舍友跟我说可以用python的第三方库——jieba库,然后我试了一下,发现真的可以,这个库也太强了吧。然后有看到题目要求,python只能提交一个python文件,可能会用不了第三方库,然后我就放弃了使用jieba库的想法,老老实实的转向正则表达。以前完全没有用过正则表达式,这次临时去学的,最后发现python的正则表达式还是挺好理解的,很快就能切分出想要的。
      
    • 拿到总的地址串之后在开始逐级细分,按照省、市、县、镇、路、门派号、详细地址的顺序一级一级进行分割。省市县镇是通过和全国的地图数据匹配得到,路、门牌号、详细地址则是通过正则表达式切分得到。

      写地址切片真的是一波三折,推到重来了好几次。
      第一个想法是用高德地图的api来做,代码量是真的少,只需要一个get请求,就自动帮你完成地址解析并返回一个json对象,但是写完之后发现,高德api的精度完全不行,只能到县级,之后的镇、路、门牌号这些都没办法给出,第一个想法宣告失败。
      第二次的想法是全部用正则表达式去一级一级切分,然后看了看题目要求,瞬间就放弃了,第二个想法也宣告失败。
      第三次的想法(准确来说,这并不是我自己的想法),同学发给了我一个有全国地图信息的json文件(省市县镇四级地址),并告诉我可以用匹配的办法来写,然后我就开始尝试,一级一级的切分,然后后地图信息进行匹配,最终达到了自己想要的目标。(这个过程也十分艰难,进了好多坑,还有一个逻辑错误,再次推到重来了一次)
      
    • 将结果保存为json格式

      通过测试程序的那一瞬间,我是真正理解了什么是痛并快乐着。从真正开始写代码到完成,花了4天左右时间。凌晨四点的福大不用等到后面的团队作业,第一次作业就能见识到了,真的累。在这里由衷感谢陈秋琴、张庆焰、许煌标三位同学,没有他们的激励和帮助,我肯定没办法完成我的作业,4天过程中,好多次想要半途而废想要放弃,但是最后并没有,是他们给了我一次次推到重来的信心和勇气。
      

    各个函数具体如下:

    函数名 说明
    def main() 主函数,并进行初步的分割,得到姓名、手机和地址串
    def cutsame() 在地址串中切掉已经匹配好的部分
    def mapmatch_5() 完成5级地址的匹配分割
    def mapmatch_7() 完成7级地址的匹配分割
    def select(flag) 通过前缀判断是进行5级分割还是7级分割

    流程图:

    整个流程的实现到不是很难,只是有各种各样需要跳过去的小坑。核心思想是采用逐级分割。前4级(省、市、县、镇)采用匹配得到,最后3级(路、门牌号、详细地址)由正则切分得到。
    例子展示如下:
    "2!李四,福建省福州13756899511市鼓楼区鼓西街道湖滨路110号湖滨大厦一层."
    步骤:
    (1)input()
    初步分割为:
    难度等级:2
    姓名:李四
    手机:13756899511
    总地址串:福建省福州市鼓楼区鼓西街道湖滨路110号湖滨大厦一层
    (2)之后再由难度等级2判断出要进行7级分割
    省:福建省  地址串:福州市鼓楼区鼓西街道湖滨路110号湖滨大厦一层(匹配)
           ↓
    市:福州市  地址串:鼓楼区鼓西街道湖滨路110号湖滨大厦一层(匹配)
           ↓
    县:鼓楼区  地址串:鼓西街道湖滨路110号湖滨大厦一层(匹配)
           ↓
    镇:鼓西街道  地址串:湖滨路110号湖滨大厦一层(匹配)
           ↓
    路:湖滨路  地址串:110号湖滨大厦一层(正则)
           ↓
    门牌号:110号  地址串:湖滨大厦一层(正则)
           ↓
    详细地址:湖滨大厦一层(正则)
    (3)最后转化为json对象
    print(json)
    

    计算模块接口部分的性能改进

    性能分析如下图所示:

    性能分析真的把我给整懵了,可能是由于我把整个中国地图的json都复制到了我的源代码里面(要求只能有一个py文件),我的代码行数达到了19W行,导致真的有利用到的代码量很少,占比很少,然后得出了这个分析结果。(我什么也看不懂,也不知道该怎么改进)
    
    占比最高的函数是 input()
    

    覆盖率如下图所示:

    覆盖率

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

    2!李四,福建省福州13756899511市鼓楼区鼓西街道湖滨路110号湖滨大厦一层.
    {"姓名": "李四", "手机": "13756899511", "地址": ["福建省", "福州市", "鼓楼区", "鼓西街道", "湖滨路", "110号", "湖滨大厦一层"]}
    
    1!张三,福建福州闽13599622362侯县上街镇福州大学10#111.
    {"姓名": "张三", "手机": "13599622362", "地址": ["福建省", "福州市", "闽侯县", "上街镇", "福州大学10#111"]}
    
    2!王五,福建省福州市鼓楼18960221533区五一北路123号福州鼓楼医院.
    {"姓名": "王五", "手机": "18960221533", "地址": ["福建省", "福州市", "鼓楼区", "", "五一北路", "123号", "福州鼓楼医院"]}
    
    3!小美,北京市东15822153326城区交道口东大街1号北京市东城区人民法院.
    {"姓名": "小美", "手机": "15822153326", "地址": ["北京", "北京市", "东城区", "交道口街道", "东大街", "1号", "北京市东城区人民法院"]}
    
    1!小陈,广东省东莞市凤岗13965231525镇凤平路13号.
    {"姓名": "小陈", "手机": "13965231525", "地址": ["广东省", "东莞市", "", "凤岗镇", "凤平路13号"]}
    
    1!韶划奸,上海市普陀15717060981区长风新村街道光复西路1995号中山北路6-17号海鑫公寓.
    {"姓名": "韶划奸", "手机": "15717060981", "地址": ["上海", "上海市", "普陀区", "长风新村街道", "光复西路1995号中山北路6-17号海鑫公寓"]}
    
    1!钭洋,福建龙岩新罗区岩山镇岩山供销社黄固村农资农家店13135601243.
    {"姓名": "钭洋", "手机": "13135601243", "地址": ["福建省", "龙岩市", "新罗区", "岩山镇", "岩山供销社黄固村农资农家店"]}
    
    2!楚涡握,湖北随州市随县吴山镇唐王街联宏村委18883549874会.
    {"姓名": "楚涡握", "手机": "18883549874", "地址": ["湖北省", "随州市", "随县", "吴山镇", "唐王街", "", "联宏村委会"]}
    

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

    #县   
    #县级有可能会有确实,需要特殊处理
    #在遍历县级地址时,若发现未找到,则flag会为0
    #并使data["县"] = ""(空串)
        match = address_str[:2]
        #print(address_str)
        flag = 0    									#flag是异常处理的关键所在
        for item in itemm["children"]:
            if(re.search(match,item["name"])):
                itemm = item   #如果县级缺失,就不会有这个
                flag = 1
                break
        if(flag == 1):
            data["县"] = itemm["name"]
        else:
            data["县"] = ""
            
        address_str = cutsame(itemm["name"],address_str)
        
    #镇
    #当flag==0使,则表示在上一级未找到县级地址
    #因此要匹配到镇级地址,就必须遍历整个市区内的所有镇
    #用一个双层for循环实现
        match = address_str[:2]
        itemmm = {"name":""}
        #print(address_str)
        if(flag == 1):
            for item in itemm["children"]:
                if(re.search(match,item["name"])):
                    itemmm = item
                    break
        else:
            for item in itemm["children"]:
                for item2 in item["children"]:       #双循环遍历
                    if(re.search(match,item2["name"])):
                        itemmm = item2
                        break
    
        data["镇"] = itemmm["name"]
        address_str = cutsame(itemmm["name"],address_str)
     
    
    #正则切片的时候也会有缺失
    #但是用一个if判断就可以完美解决
    #因为如果未找到目标,会返回一个none对象,可以作为if判断的条件
    def mapmatch_7():
        address_str = data["详细地址_5"]
        #街道
        c = re.compile(r'.+(路|街|巷|桥|道){1}')
        match_1 = c.search(address_str)
        #print(match.group(0))
        if(match_1):    
            data["街道"] = match_1.group(0)
        else:   #如果为none,则赋值为空串    核心
            data["街道"] = ""
        address_str = cutsame(data["街道"],address_str)
        #print(data["街道"])
        #print(address_str)
    
        #门牌号
        cc = re.compile(r'.+(号){1}')
        match_2 = cc.search(address_str)
        #print(match.group(0))
        if(match_2):
            data["门牌号"] = match_2.group(0)
        else:    #如果为none,则赋值为空串       核心
            data["门牌号"] = ""
        address_str = cutsame(data["门牌号"],address_str)
        #print(data["门牌号"])
        #print(address_str)
        data["详细地址_7"] = address_str
    
    #遇到最大的坑应该就是这两个了,其他还有一些零零散散的小问题,比较容易解决
    

    心得体会

    心得体会已经写在了解题思路里边了。

  • 相关阅读:
    微信小程序传参 查询数据库,显示在小程序上
    jquery 的$.ajax() 与php后台交互
    Laravel 7 中文文档
    phpStudy配置
    Mysql 聚合函数 嵌套使用
    MySQL 的IFNULL()、ISNULL()和NULLIF()函数
    MySQL 定义变量,并且可以当value 值插入
    排序算法之冒泡排序
    排序算法之快速排序
    链表之反转链表
  • 原文地址:https://www.cnblogs.com/phd1999/p/11533065.html
Copyright © 2011-2022 走看看