蓝桥楼赛23期


好久没有更新博客,前几天被朋友拉入坑参加蓝桥楼赛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
    排名
  • 评论区已经有老哥发飙了
    评论
  • 心态不好不建议参加
  • 奖品到了再补照片
  • 奖品到了,补:

奖品


文章作者: Tqraf
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Tqraf !
评论
  目录