第一次个人编程作业

作业地址

作业地址:https://github.com/ssf-czh/031702530 (first_homework python环境)

利用PSP表格记录下估计将在程序的各个模块的开发上耗费的时间

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

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

示例

示例1:2!李四,福建省福州13756899511市鼓楼区鼓西街道湖滨路110号湖滨大厦一层.
示例2:1!张三,福建福州闽13599622362侯县上街镇福州大学10#111.
示例3:2!王五,福建省福州市鼓楼18960221533区五一北路123号福州鼓楼医院.
示例4:3!小美,北京市东15822153326城区交道口东大街1号北京市东城区人民法院.
示例5:1!小陈,广东省东莞市凤岗13965231525镇凤平路13号.

针对该问题设计了一个工具类(Address_Tool),这个工具类针对不同问题难度设计了不同的求解方法,这几个方法又有其依赖关系。

比如方法1 strToPhone 解决了电话号码混杂在字符串的问题(示例一1!张三,福建福州闽13599622362侯县上街镇福州大学10#111.),并且返回一个干净的字符串(记录并剔除了姓名和电话号码福建福州闽侯县上街镇福州大学10#111

方法2 divToFive 解决了难度1的问题(示例一1!张三,福建福州闽13599622362侯县上街镇福州大学10#111.),并且返回经过处理的列表({"姓名": "张三", "手机": "13599622362", "地址": ["福建省", "福州市", "闽侯县", "上街镇", "福州大学10#111"]})。

方法3 divToSeven 解决了难度2的问题(示例一2!李四,福建省福州13756899511市鼓楼区鼓西街道湖滨路110号湖滨大厦一层.),通过复用方法2 divToFive 并且返回经过处理的列表({"姓名": "张三", "手机": "13599622362", "地址": ["福建省", "福州市", "闽侯县", "上街镇", "福州大学10#111"]}),再将地址子段中的最后一级地址进行切割,得到最终结果({"姓名": "李四", "手机": "13756899511", "地址": ["福建省", "福州市", "鼓楼区", "鼓西街道", "湖滨路", "110号", "湖滨大厦一层"]})。

方法4 autoCorrAll 解决了难度3的问题(示例四3!小美,北京市东15822153326城区交道口东大街1号北京市东城区人民法院.),通过复用方法3 divToSeven 并且返回经过处理的列表({"姓名": "小美", "手机": "15822153326", "地址": ["北京", "北京市", "东城区", "", "交道口东大街", "1号", "北京市东城区人民法院"]}),再通过高德地图API进行详细信息的补全(API点此进入),将申请到的信息填充到列表中缺失的位置(具体步骤请看github),得到最最终答案。

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

首先对类中的方法接口进行分析,类的方法分为以上的四种方法,方法的调用取决于输入的字符串,根据输入的字符串的类型(x!通过x来判断其类型)来调用不同的方法

方法一strToPhone是用过正则匹配其字符串,其消耗的时间开始很小,几乎可以忽略不计,而且这也是程序没必要提升的地方。

当方法divToFive处理难度1的问题时,可以看到其开销很小,最大部分的时间消耗处在对省份列表,城市列表和区列表的遍历,但这些对于现代计算机来说是微不足道的。

当方法divToSeven处理难度2的问题时,同样的其开销也很小,针对难度二方法实质上是对方法一的复用,再增添额外的代码,与方法一函数的性能相差无几。

当方法autoCorrAll处理难度3的问题时,可以看到其性能大大减小,增加的时间消耗也特别高,纠其原因也显而易见,它调用了requests库,而且在此方法解决难度三的问题时是通过调用API来解决问题,其性能往往取决于当时的网络状况,毫无疑问,网络状况好的话,其性能会有所提高,反之也同样成立。

因此该程序的性能瓶颈很大一部分取决于网络情况因素。

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

在单元测试中,利用python自带的unittest,其目的是检测每个单一功能的准确性,即你的方法在输入数据之后能够达到你所想要的结果,在此对每一个函数进行单元测试。

可以看到,所有的函数都经过单元测试的检验。

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

由于业务逻辑是我们自己实现,故在代码业务逻辑不会出现异常,而整个程序的出错异常点就存在于用户的输入阶段,在用户的输入阶段用户可能出现漏输,错输,在此进行异常,在此认为异常处理处于姓名和选择难度阶段还有对于逗号的分割异常还有请求是服务端的异常...

还有许多异常处理就不再一一列出

本次个人作业的体会与总结

这次的个人作业实属不易,因为本来参加了数学建模国赛,三天都没法做本次作业,于是只有俩天时间来进行问题的求解,但是第一天又满课,于是相当于只有一天的时间进行代码的编写,在这个问题中,最重要的在于数据的收集和脑洞的开发,数据的收集是针对前三级的地址,而后面的四级 包括地址的补全就要用到简单的API,虽然说方法简单,但是具体找到其接口确实不容易,而在我看来问题的求解并不困难,半天就解决了,但是问题困难的试如何利用各种评测工具来进行代码质量的测试,还有各种的单元测试,收获的还有如何通过PSP表格记录来进行时间上的规划。