[百度飞桨领航团零基础Python速成营]作业六易错点分析

第一题

数据如下:

stu1.txt 孙同学,2020-5-21,20,'男',77,56,77,76,92,58,-91,84,69,-91 
stu2.txt 赵同学,2020-11-3,24,'女',65,68,72,95,-81,71,86,91,57,91 
stu3.txt 王同学,2021-8-7,25,'男',87,78,90,-76,88,47,100,65,69,100 
stu4.txt 李同学,2021-8-10,29,'男',92,54,85,71,-91,68,77,68,95,95

要求如下:

定义Student类,包括name、dob、age、gender和score属性,包括top3方法用来返回学生的最大的3个成绩(可重复)、sanitize方法用来将负的分数变为正的分数,负的分数可能是输入错误。声明stu_list对象组数用于存储所有的学生对象。最后输出所有的学生信息包括姓名、生日、年龄、性别、最高的3个分数。

给出的参考输出结果:

我的代码:

class Student:
    def __init__(self, a_name, a_dob, a_age, a_gender, a_score):
        self.name = a_name
        self.dob = a_dob
        self.age = a_age
        self.gender = a_gender
        self.score = a_score
    def top3(self):
        return sorted([self.sanitize(s) for s in self.score])[-3:]
    def sanitize(self,score_string):
        if '-' in score_string:
            return int(score_string[1:])
        else:
            return int(score_string)

def get_score_data(filename):
    with open(filename) as f:
        line = f.readline()
    return line.strip().split(',')  

def print_score(student):
    print(f"姓名:{student.name},生日:{student.dob},年龄:{student.age},性别:{student.gender},分数:{student.top3()}")

student_list = []
for i in range(1,5):
    filename = 'work/stu' + str(i) + '.txt'
    stu_record = get_score_data(filename)
    stu = Student(stu_record.pop(0), stu_record.pop(0), stu_record.pop(0), stu_record.pop(0), stu_record)
    print_score(stu)
    student_list.append(stu)

我的输出:

姓名:孙同学,生日:2020-5-21,年龄:20,性别:'男',分数:[91, 91, 92]
姓名:赵同学,生日:2020-11-3,年龄:24,性别:'女',分数:[91, 91, 95]
姓名:王同学,生日:2021-8-7,年龄:25,性别:'男',分数:[90, 100, 100]
姓名:李同学,生日:2021-8-10,年龄:29,性别:'男',分数:[92, 95, 95]

易错点1:top3成绩取的是非重复值的排序,而非包含重复值的排序。分析发现,之所以出现这一差别,原因在于老师在课上给出的代码中使用了set()函数,而set()函数的作用是删除重复值。现在让我们来看一下使用set()函数的代码段:

def top3(self):
    return sorted(set([self.sanitize(s) for s in self.score]))[-3:]

此时的输出为:

姓名:孙同学,生日:2020-5-21,年龄:20,性别:'男',分数:[84, 91, 92]
姓名:赵同学,生日:2020-11-3,年龄:24,性别:'女',分数:[86, 91, 95]
姓名:王同学,生日:2021-8-7,年龄:25,性别:'男',分数:[88, 90, 100]
姓名:李同学,生日:2021-8-10,年龄:29,性别:'男',分数:[91, 92, 95]

易错点2:王同学的100去哪儿了?先看错误的输出:

姓名:孙同学,生日:2020-5-21,年龄:20,性别:'男',分数:['91', '91', '92']
姓名:赵同学,生日:2020-11-3,年龄:24,性别:'女',分数:['91', '91', '95']
姓名:王同学,生日:2021-8-7,年龄:25,性别:'男',分数:['87', '88', '90']
姓名:李同学,生日:2021-8-10,年龄:29,性别:'男',分数:['92', '95', '95']

究其原因,是因为此时的分数列表中的分数是字符串格式,而字符串的排序是从逐位排序的,先比较第一个字符,第一个字符相同的情况下再比较第二个字符,以此类推,所以字符串‘100’反而是最小的,所以我们要取top3值是取不到的。所以需要把以下代码段的返回值取整。

def sanitize(self,score_string):
    if '-' in score_string:
        return score_string[1:]
    else:
        return score_string

第二题

数据如下:

stu5.txt 特长同学,2020-10-5,20,'男',180,87,98,77,76,92,58,-76,84,69,-47
stu6.txt 特长同学,2020-10-6,20,'女',230,76,48,82,88,92,58,-91,84,69,-68

要求如下:

定义Spostudent、Artstudent为Student的子类,在子类的属性里面新增了spe为特长分数。Spostudent包括的top3方法返回的是最低的3个得分(可重复),Artstudent包括top3方法返回的是最高的3个得分(可重复),最后使用多态的方式输出2个特长同学的姓名、生日、年龄、性别、分数、特长分。

给出的参考输出结果:

我的代码:

class Student:
    def __init__(self, a_name, a_dob, a_age, a_gender, a_score):
        self.name = a_name
        self.dob = a_dob
        self.age = a_age
        self.gender = a_gender
        self.score = a_score
    def top3(self):
        return sorted(set([self.sanitize(s) for s in self.score]))[0:3]
    def sanitize(self,score_string):
        if '-' in score_string:
            return int(score_string[1:])
        else:
            return int(score_string)

class Spostudent(Student):
    def __init__(self, a_name, a_dob, a_age, a_gender, a_spe, a_score):
        Student.__init__(self, a_name, a_dob, a_age, a_gender, a_score)
        self.spe = a_spe

class Artstudent(Student):
    def __init__(self, a_name, a_dob, a_age, a_gender, a_spe, a_score):
        Student.__init__(self, a_name, a_dob, a_age, a_gender, a_score)
        self.spe = a_spe
    def top3(self):
        return sorted([self.sanitize(s) for s in self.score])[-3:]

def get_score_data(filename):
    with open(filename) as f:
        line = f.readline()
    return line.strip().split(',')  

def print_score(student):
    print(f"姓名:{student.name},生日:{student.dob},年龄:{student.age},性别:{student.gender},分数:{student.top3()},特长分:{student.spe}")

spoStudent = get_score_data('work/stu5.txt')
spoStudent = Spostudent(spoStudent.pop(0), spoStudent.pop(0), spoStudent.pop(0), spoStudent.pop(0), spoStudent.pop(0), spoStudent)
print_score(spoStudent)
artStudent = get_score_data('work/stu6.txt')
artStudent = Artstudent(artStudent.pop(0), artStudent.pop(0), artStudent.pop(0), artStudent.pop(0), artStudent.pop(0), artStudent)
print_score(artStudent)

易错点3:为什么我输出的分数是个空列表?错误的输出如下:

姓名:特长同学,生日:2020-10-5,年龄:20,性别:'男',分数:[],特长分:180
姓名:特长同学,生日:2020-10-6,年龄:20,性别:'女',分数:[],特长分:230

错误的代码段:

class Spostudent(Student):
    def __init__(self, a_name, a_dob, a_age, a_gender, a_spe, a_score):
        Student.__init__(self, a_name, a_dob, a_age, a_gender, a_score=[])
        self.spe = a_spe

class Artstudent(Student):
    def __init__(self, a_name, a_dob, a_age, a_gender, a_spe, a_score):
        Student.__init__(self, a_name, a_dob, a_age, a_gender, a_score=[])
        self.spe = a_spe

原因分析:在定义Spostudent和Artstudent类时,在初始化对象时,'a_score=[]'的作用是将父类student的a_score属性重写为一个空的列表,所以不管传入的参数是什么,最后的输出都会是重写后的空列表。这里很多同学和老师给出的例子搞混了:

class Student:
    def __init__(self, a_name, a_dob, a_age, a_gender, a_score=[]):
        self.name = a_name
        self.dob = a_dob
        self.age = a_age
        self.gender = a_gender
        self.score = a_score

为什么在老师的例子中,'a_score=[]'并没有影响最后的输出呢,这是因为'a_score=[]'在这里定义的是一个默认参数,当没有参数传入时,a_score将默认赋值为一个空列表。两者的含义是不同的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值