第一次个人编程作业
1.本次作业的github地址链接:
https://github.com/South1999/111700312.git
2.PSP表格
| PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
|---|---|---|---|
| Planning | 计划 | 20(sum) | |
| ·Estimate | ·估计这个任务需要多少时间 | 20 | |
| Development | 开发 | 490(sum) | |
| ·Analysis | ·需求分析 (包括学习新技术) | 120 | |
| ·Design Spec | ·生成设计文档 | 10 | |
| ·Design Review | ·设计复审 | 20 | |
| ·Coding Standard | ·代码规范 | 30 | |
| ·Design | ·具体设计 | 60 | |
| ·Coding | ·具体编码 | 90 | |
| ·Code Review | ·代码复审 | 40 | |
| ·Test | ·测试 | 120 | |
| Reporting | 报告 | 80(sum) | |
| ·Test Repor | ·测试报告 | 20 | |
| ·Test Repor | ·计算工作量 | 20 | |
| ·Postmortem & Process Improvement Plan | ·事后总结, 并提出过程改进计划 | 40 | |
| · 合计 | 590 |
3.计算模块接口的设计与实现过程
本次实现作业我是分为七个部分来写。
举个例子,输入为 2!钮衷,上海市长宁区虹桥街道15839057873虹桥路996号长虹小区.
- 第一部分首先把难度等级提取出来,因为难度等级只有一位数字且一定是在第一位,把第一位保存下来就好,然后把第二位和最后一位无用的标点符号处理掉。此时提取出“2”,剩下“钮衷,上海市长宁区虹桥街道15839057873虹桥路996号长虹小区”。
- 第二部分是把名字提取出来,因为名字后面会跟着一个逗号,可以按顺序读取字符串,遇到逗号时停止,保存逗号之前的字符串,也就是名字,然后把逗号和名字部分处理掉。此时提取出“钮衷”,剩下“上海市长宁区虹桥街道15839057873虹桥路996号长虹小区”。
- 第三部分是提取手机号码,手机号码是11位的数字而且不会和其他数字连在一起,可以遍历字符串,连续出现十一个数字的时候停止,把这十一位保存下来,然后再从字符串中删去这十一个数字。此时提取出“15839057873”,剩下“上海市长宁区虹桥街道虹桥路996号长虹小区”
- 第四部分是提取省市,读取已经预处理的省市地址数据,我用到了字典,键是省,值是市,然后在字符串中去分别查找对应的省和市,有就保存下来,没有就空着,省级单位四个直辖市和一些自治区要特判,市级单位特判自治州和盟和地区,然后把省市级单位从字符串中去掉。此时提取出“上海市”,这里会自动处理出省和市的结果,剩下“长宁区虹桥街道虹桥路996号长虹小区”。
- 第五部分是处理县级地址,按照关键字“区”“县”“市”来查找,提取之后把县级单位从中删去。此时提取出“长宁区”,剩下“虹桥街道虹桥路996号长虹小区”。
- 第六部分提取乡级单位,乡级单位我也是用寻找关键字来提取,然后有就保存下来,没有就为空,之后把乡级单位从字符串中删去。此时提取出“虹桥街道”,剩下“虹桥路996号长虹小区”。
- 第七部分是处理最后一部分的数据,如果是五级地址,直接把剩下的数据直接保存下来就好,如果是七级地址,剩下路名和号码还是按照寻找关键字的方法来提取,最后剩下来的数据就是详细地址。把七个部分连接在一起的就是最初输入的那个字符串,每个部分所用到的字符串一定要是上一部分处理之后的字符串,不可以用原始的。此时提取出“虹桥路”“996号”“长虹小区”,提取结束。
最终结果{'姓名': '钮衷', '手机': '15839057873', '地址': ['上海', '上海市', '长宁区', '虹桥街道', '虹桥路', '996号', '长虹小区']}。
本次作业算法的关键就是关键字的匹配,用到python中的str.find()函数,通过来查找“省”“市”“县”“乡”等一系列关键字来分割各级地址,由于省市级地址可能会缺失关键字,我就把省市地址放在一个文件中,直接匹配名字而不是匹配关键字。特殊的地方在于因为有些地址可能会缺失,而这些地址的关键字可能在下一级地址中出现,所以我限制了查询的位置,如果查询到关键字的位置大于某个值,就把这个地址划分到下一级,这样做可以增加一些正确的概率,但也可能使原本对的值划分错误。
4.计算模块接口部分的性能改进。


(测试性能我输入了多组数据,数据较少会没有结果)
改进性能上大概花了二十分钟,因为我所写的函数用到的算法都是比较简单的,改进的空间不多,在查找过程中如果找到关键字就直接break,可以节约一些时间。消耗最大的函数如下:
def sol_p_c(msg):
# 读入地址文件
fp = open('address.txt', mode="r", encoding="utf-8", errors="ignore")
addr = eval(fp.read())
# 分离出省市,并处理
province = ""
city = ""
for key in addr.keys():
if (msg.find(key) >= 0):
if (msg[len(key)] == '省'):
province = key
msg = msg[len(key) + 1:]
else:
province = key
msg = msg[len(key):]
for ad in addr[key]:
if (msg.find(ad) >= 0):
if (msg[len(ad)] == '市'):
city = ad
msg = msg[len(ad) + 1:]
break
else:
city = ad
msg = msg[len(ad):]
break
break
if (province == '北京' or province == '天津' or province == '重庆' or province == '上海'):
if (msg[0] == '市'):
msg = msg[1:]
city = province
elif (province != "" and province[len(province) - 1] != '区'):
province += '省'
if (city.find('区') == -1 and city.find('自治州') == -1 and city.find('盟') == -1):
if (city != ''):
city += '市'
return msg, province, city
5.计算模块部分单元测试
输入:
1!荣蛇梗,海南省海口市琼山区红旗镇道崇村村邮15864093013站.
1!单滓坡,13698659990安徽铜陵义安区*联镇011县道汀洲村党群综合服务中心.
1!於检,宁夏回族自治区吴忠市同心县豫13009901693海镇银**街140号城二餐厅.
1!明赠,13485907938山*省*中市*遥县南关大街30号城南堡党支部村委会.
1!罗鹏,重庆满月乡月13855683225发街1号开州区满月乡公共卫生管理中心.
2!刁俱嗜,广东省珠海市斗门13516594285区井岸镇井岸渡江路朝福苑飞龙二区3号楼.
2!戎菱怠,河南*顶山市新华区*市场街道*安大道红旗街小区16号楼13726321206.
2!伯箍,山东省烟台市蓬莱市南王街道半岛蓝庭4期10号13757416720楼.
2!苍逛,广*壮族自治区来宾市兴宾区河*街道文明路64号河15165696049*街道缤纷社区居务监督委员会.
2!满茧腌,湖北省鄂州市涂家垴镇发13387889865展路9号鄂州市涂家垴派出所.
3!符乡,安徽大观区菱湖街道宜园13281503317路80号.
3!褚佳,浦13447146058东新区惠南镇靖海路440号靖海桥大楼.
输出:
{'姓名': '荣蛇梗', '手机': '15864093013', '地址': ['海南省', '海口市', '琼山区', '红旗镇', '道崇村村邮站']}
{'姓名': '单滓坡', '手机': '13698659990', '地址': ['安徽省', '铜陵市', '义安区', '*联镇', '011县道汀洲村党群综合服务中心']}
{'姓名': '於检', '手机': '13009901693', '地址': ['宁夏回族自治区', '吴忠市', '同心县', '豫海镇', '银**街140号城二餐厅']}
{'姓名': '明赠', '手机': '13485907938', '地址': ['山*省', '*中市', '*遥县', '', '南关大街30号城南堡党支部村委会']}
{'姓名': '罗鹏', '手机': '13855683225', '地址': ['重庆', '重庆市', '', '满月乡', '月发街1号开州区满月乡公共卫生管理中心']}
{'姓名': '刁俱嗜', '手机': '13516594285', '地址': ['广东省', '珠海市', '斗门区', '井岸镇', '井岸渡江路', '', '朝福苑飞龙二区3号楼']}
{'姓名': '戎菱怠', '手机': '13726321206', '地址': ['河南省', '*顶山市', '新华区', '*市场街道', '*安大道', '', '红旗街小区16号楼']}
{'姓名': '伯箍', '手机': '13757416720', '地址': ['山东省', '烟台市', '蓬莱市', '南王街道', '', '', '半岛蓝庭4期10号楼']}
{'姓名': '苍逛', '手机': '15165696049', '地址': ['广*壮族自治区', '来宾市', '兴宾区', '河*街道', '文明路', '64号', '河*街道缤纷社区居务监督委员会']}
{'姓名': '满茧腌', '手机': '13387889865', '地址': ['湖北省', '鄂州市', '', '涂家垴镇', '发展路', '9号', '鄂州市涂家垴派出所']}
{'姓名': '符乡', '手机': '13281503317', '地址': ['安徽省', '', '大观区', '菱湖街道', '宜园路', '80号', '']}
{'姓名': '褚佳', '手机': '13447146058', '地址': ['', '', '浦东新区', '惠南镇', '靖海路', '440号', '靖海桥大楼']}
代码覆盖率

评测工具结果

6.计算模块部分异常处理说明。
1!佘吏,浙江省湖州市和孚镇李市村15054267850获港大桥南堍费伟民疼痛诊所.
错误输出:{'姓名': '佘吏', '手机': '15054267850', '地址': ['浙江省', '湖州市', '和孚镇李市', '', '村获港大桥南堍费伟民疼痛诊所']}
正确答案:{"姓名": "佘吏", "手机": "15054267850", "地址": ["浙江省", "湖州市", "", "和孚镇", "李市村获港大桥南堍费伟民疼痛诊所"]}
- 这条数据是因为缺失县级地址,但是下一级地址出现了县级地址的关键字“市”,导致分割地址出错。
1!翁庆,江苏省13860627003宿迁市宿城区172乡道罗圩中心小学.
错误输出:{'姓名': '翁庆', '手机': '13860627003', '地址': ['江苏省', '宿迁市', '宿城区', '172乡', '道罗圩中心小学']}
正确答案:{"姓名": "翁庆", "手机": "13860627003", "地址": ["江苏省", "宿迁市", "宿城区", "", "172乡道罗圩中心小学"]}
- 这条数据出错是因为“乡道”是不可分割的,但是“乡道”中有关键字“乡”,错误地分割开。
2!丰缓,天津13608320376市滨海新区新城镇新城村东里5号新城中学.
错误输出:{'姓名': '丰缓', '手机': '13608320376', '地址': ['天津', '天津市', '滨海新区', '新城镇', '新城村', '东里5号', '新城中学']}
正确答案:{"姓名": "丰缓", "手机": "13608320376", "地址": ["天津", "天津市", "滨海新区", "新城镇", "新城村东里", "5号", "新城中学"]}
- 这条数据出错是因为路名级单位关键字判断错误。
2!柳吻,辽宁省大连市中山区青泥13013864707洼桥街道上海路45号宏孚大厦苏宁易购.
错误输出:{'姓名': '柳吻', '手机': '13013864707', '地址': ['上海', '上海市', '大连市', '', '', '', '中山区青泥洼桥街道上海路45号宏孚大厦苏宁易购']}
正确答案 :{ "姓名": "柳吻", "手机": "13013864707", "地址": ["辽宁省", "大连市", "中山区", "青泥洼桥街道", "上海路", "45号", "宏孚大厦苏宁易购"]}
- 在判断省级地址时,因为我的地址数据上海排在辽宁前面,所以导致误把路名判断成省级单位。
3!符乡,安徽大观区菱湖街道宜园13281503317路80号.
错误输出:{'姓名': '符乡', '手机': '13281503317', '地址': ['安徽省', '', '大观区', '菱湖街道', '宜园路', '80号', '']}
正确答案 :{"level": 3, "姓名": "符乡", "手机": "13281503317", "地址": ["安徽省", "安庆市", "大观区", "菱湖街道", "宜园路", "80号", ""]}
- 第三种难度地地址需要爬虫等技术,本次作业中没有写相关函数。
7.完整PSP表格
| PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
|---|---|---|---|
| Planning | 计划 | 20(sum) | 20(sum) |
| ·Estimate | ·估计这个任务需要多少时间 | 20 | 20 |
| Development | 开发 | 490(sum) | 795(sum) |
| ·Analysis | ·需求分析 (包括学习新技术) | 120 | 150 |
| ·Design Spec | ·生成设计文档 | 10 | 10 |
| ·Design Review | ·设计复审 | 20 | 15 |
| ·Coding Standard | ·代码规范 | 30 | 20 |
| ·Design | ·具体设计 | 60 | 90 |
| ·Coding | ·具体编码 | 90 | 150 |
| ·Code Review | ·代码复审 | 40 | 60 |
| ·Test | ·测试 | 120 | 300 |
| Reporting | 报告 | 80(sum) | 110(sum) |
| ·Test Repor | ·测试报告 | 20 | 30 |
| ·Test Repor | ·计算工作量 | 20 | 20 |
| ·Postmortem & Process Improvement Plan | ·事后总结, 并提出过程改进计划 | 40 | 60 |
| · 合计 | 590 | 925 |
简单总结
这次实验在测试上花费了最长时间,总的来说就是我的考虑不够全面,我在之后的修改又加了一些特判,加了一些搜索的关键字,分数有所上升,但是我查看了我错误的测试,发现有些数据我无法保证都兼顾到,原因还是算法不够好,我只用了简单的搜索关键字。而且刚开始也是粗心,自己写的地址数据没有写全。第三级难度需要用爬虫去爬取地图数据,但是短时间内我学不会,也算是这次作业的遗憾,之后我会努力补上。

浙公网安备 33010602011771号