好久没有更新博客,前几天被朋友拉入坑参加蓝桥楼赛23期Python项目挑战赛,过程坎坷,特来吐槽
比赛介绍
- 项目地址:https://www.lanqiao.cn/contests/lou23/challenges/
- 项目规则:分别在9月15号、17号、19号晚20:00发出三个赛题,需要在蓝桥提供的实验环境中提交检测,先完成的得分高
- 项目奖励:前十名获得实验楼纪念品(抱枕+小风扇),前两名邀请加入百楼俱乐部
反正闲着也是闲着(
冲着奖品来的)
赛题一
1.解析用户名字符串
- 要求其实很简单:解析字符串,提取
@
符号后面的用户名(中文字符、下划线、数字和英文字母组成,不包含标点符号、空格和其他特殊字符) - 不能使用标准库和第三方库
2.代码
def after_at(text):
usernames = []
split_list = text.split("@")[1:]
for split_text in split_list:
username = ""
for char in split_text:
if ('\u4e00' <= char <= '\u9fff') or (u'\u0041' <= char <= u'\u005A') or (u'\u0061' <= char <= u'\u007A') or (char == u'\u005f'):
username += char
else:
break
if username:
usernames.append(username)
usernames_set = []
# 以下是排序
for i in usernames:
if i not in usernames_set:
usernames_set.append(i)
usernames_list2d = []
for i in usernames_set:
num = 0
for j in range(len(usernames)):
if usernames[j] == i:
num += 1
a = []
a.append(i)
a.append(num)
usernames_list2d.append(a)
for i in range(len(usernames_list2d)):
for j in range(i, len(usernames_list2d)):
if usernames_list2d[i][1] < usernames_list2d[j][1]:
usernames_list2d[i],usernames_list2d[j] = usernames_list2d[j], usernames_list2d[i]
usernames = [i[0] for i in usernames_list2d]
return usernames
3.吐槽
- 首先,第一题完全就是个坑
- 其次,代码很简单,先将字符串按
@
分割成列表,检测每个元素中@后符合条件的字符,提取出来就是用户名。 - 最后,按照要求函数返回列表,且应按 text 字符串中的出现的正确用户名次数降序排列,次数相等无先后顺序,且不重复,排序只需要将用户名和它出现的次数做成一个字典,再使用
sorted
排序即可,那这里的排序为何如此复杂? - 因为后来才知道是官方检测脚本有问题,导致正确的代码不能提交成功,所以我就各种找问题再尝试。按照测试样例,出现此数相等的用户名,应该按照出现顺序排序,如果使用
sorted
并带上reverse=True
参数,就会导致出现次数相等的用户名顺序反过来,所以大费周章换个排序方法。 - 在尝试了所有办法之后,提交仍然不成功,向客服反馈后,增加了测试用例,测试正确但仍然提交不成功,本打算放弃这个比赛。一天后抱着尝试的态度再次提交了之前提交过的代码,竟然是通过了!
- 然而已经过去了一天,提交人数很多了,没获得额外加分,就很气。
赛题二
1.工作文件整理归类
- 要求也很简单:整理指定文件夹中的文件,按照特定规则将文件整理到对应文件夹中
- 可以使用标准库
2.代码
import os
def clean_up(folder):
file_list = {}
shotnames = []
extensions = []
filenames = os.listdir(folder)
for filename in filenames:
shotname, extension = os.path.splitext(filename)
shotnames.append(shotname)
extensions.append(extension)
file_list['others'] = 0
# no extension
for i in range(len(shotnames)):
if not extensions[i]:
file_list['others'] += 1
if not os.path.exists(folder + '/others'):
os.makedirs(folder + '/others')
os.rename(folder + '/' + shotnames[i], folder + '/others/' + shotnames[i])
shotnames[i] = ''
extensions[i] = ''
# same name
for i in range(len(shotnames)):
if shotnames[i] and shotnames.count(shotnames[i]) >= 2:
file_list[shotnames[i]] = 0
if not os.path.exists(folder + '/'+shotnames[i]):
os.makedirs(folder + '/'+shotnames[i])
for j in [k for k, a in enumerate(shotnames) if a == shotnames[i]]:
file_list[shotnames[j]] += 1
os.rename(folder + '/' + shotnames[j]+extensions[j], folder + '/'+shotnames[j] + '/' + shotnames[j] + extensions[j])
shotnames[j] = ''
extensions[j] = ''
# same extension
for i in range(len(extensions)):
if extensions[i] and extensions.count(extensions[i]) >= 1:
file_list[extensions[i][1:]] = 0
if not os.path.exists(folder + '/' + extensions[i][1:]):
os.makedirs(folder + '/' + extensions[i][1:])
for j in [k for k, a in enumerate(extensions) if a == extensions[i]]:
file_list[extensions[j][1:]] += 1
os.rename(folder + '/' + shotnames[j] + extensions[j], folder + '/' + extensions[j][1:] + '/' + shotnames[j] + extensions[j])
shotnames[j] = ''
extensions[j] = ''
file_list = dict(sorted(file_list.items(), key = lambda x:x[1], reverse = True))
return file_list
3.感想
- 代码分三步走,先整理没有后缀名的文件,再整理相同文件名的文件,最后整理相同后缀名的文件。
- 这题没有坑,写完代码提交就检测成功
赛题三
1.新冠疫情数据统计
- 要求:读取新冠疫情统计数据
csv
文件,统计全球各大洲的确诊人数、死亡人数、康复人数、现有人数 - 可以使用标准库和第三方库
- 注:新的坑又来了
2.代码
import csv
import json
import country_converter as coco
def count(data):
coco.logging.getLogger().setLevel(coco.logging.CRITICAL)
converter = coco.CountryConverter()
results = {'Confirmed': {}, 'Deaths': {}, 'Recovered': {}, 'Active': {}}
confirmed = {"Africa": 0, "Asia": 0, "Oceania": 0, "Europe": 0, "America": 0, "Others": 0, "Total": 0}
deaths = {"Africa": 0, "Asia": 0, "Oceania": 0, "Europe": 0, "America": 0, "Others": 0, "Total": 0}
recovered = {"Africa": 0, "Asia": 0, "Oceania": 0, "Europe": 0, "America": 0, "Others": 0, "Total": 0}
active = {"Africa": 0, "Asia": 0, "Oceania": 0, "Europe": 0, "America": 0, "Others": 0, "Total": 0}
with open(data, 'r') as f:
reader = list(csv.reader(f))
for row in reader[1:]:
if row[13] == "XKS":
row[13] = "XKX"
continent = converter.convert(names=row[13], src='ISO3', to='continent')
row[4] = 0 if not row[4] else int(float(row[4]))
row[5] = 0 if not row[5] else int(float(row[5]))
row[6] = 0 if not row[6] else int(float(row[6]))
row[7] = 0 if not row[7] else int(float(row[7]))
if row[4] - row[5] - row[6] == row[7]:
if continent != "not found":
confirmed[continent] += row[4]
deaths[continent] += row[5]
recovered[continent] += row[6]
active[continent] += row[7]
else:
confirmed["Others"] += row[4]
deaths["Others"] += row[5]
recovered["Others"] += row[6]
active["Others"] += row[7]
confirmed["Total"] = sum(i for i in confirmed.values())
deaths["Total"] = sum(i for i in deaths.values())
recovered["Total"] = sum(i for i in recovered.values())
active["Total"] = sum(i for i in active.values())
results["Confirmed"] = confirmed
results["Deaths"] = deaths
results["Recovered"] = recovered
results["Active"] = active
# results = "(results = " + json.dumps(results) + ")"
results = json.dumps(results)
return results
3.吐槽
- 先说代码吧,csv文件中只包含国家/地区的ISO3标准代码,需要使用
country_converter
将其转换为所在的洲。另外数据中的空字符串不能直接转换为int类型,需要先找到空字符串并写0
槽点1
来看题目要求函数需要返回的json数据(字符串类型)
是不是也以为需要在
json.dumps(results)
前后加上(results =
和)
,实际情况则是不能加,返回值应为标准的json数据
{
"Confirmed": {
"Africa": 1203094,
"Asia": 6480321,
"Oceania": 27346,
"Europe": 3450299,
"America": 6396173,
"Others": 721,
"Total": 17557954
},
"Deaths": {
"Africa": 28289,
"Asia": 133186,
"Oceania": 576,
"Europe": 206438,
"America": 254610,
"Others": 15,
"Total": 623114
},
"Recovered": {
"Africa": 930536,
"Asia": 5163062,
"Oceania": 21892,
"Europe": 1927545,
"America": 5087347,
"Others": 651,
"Total": 13131033
},
"Active": {
"Africa": 244269,
"Asia": 1184073,
"Oceania": 4878,
"Europe": 1316316,
"America": 1054216,
"Others": 55,
"Total": 3803807
}
}
槽点2
- 题目描述count(data)函数最终返回数据格式示例如下(数据非真实情况),看看所给的示例,
"Confirmed": {"Africa": 1203024
,这个1203024
与真实数字1203094
只差70
,看到结果第一眼就想检查哪里的数据不对。最后统计一下Total
才发现示例的数字完全是非真实情况。 - 不给正确的数据也就算了,既然给个非真实数据,好歹像个非真实的样子啊-_-
槽点3
- csv文件中有一个国家为Kosovo,对应代码
XKX
,使用country_converter
转换结果为not found
,百度一下才发现这个国家/地区代码应为XKS
,如果不做处理就会被归类到Others
类别中去,造成提交不通过。所以需要单独把这个拎出来改成XKS
。(已经试验过,不作处理不通过)
槽点4
- 19号晚立即写完代码,尝试各种方法提交不通过,猜测检测脚本有问题,一直到20号,提交多次都不通过。最后在结束前半个小时想起来,尝试再次提交了,通过
总结
- 两次抢先提交失败,获得额外分较少,排名第9
- 评论区已经有老哥发飙了
- 心态不好不建议参加
- 奖品到了再补照片
- 奖品到了,补: