美文网首页
head first python(第六章)–学习笔记

head first python(第六章)–学习笔记

作者: dnaEMx | 来源:发表于2015-05-15 00:47 被阅读238次

    样例数据

    Sarah Sweeney,2002-6-17,2:58,2.58,2:39,2-25,2-55,2:54,2.18,2:55,2:55,2:22,2-21,2.22
    

    需要将数据整理,实现人名+出生日期+成绩的输出

    以往的做法是:

    def sanitize(time_string):
        if '-' in time_string:
            splitter = '-'
        elif ':' in time_string:
            splitter = ':'
        else:
            return(time_string)
        (mins, secs) = time_string.split(splitter)
        return(mins + '.' + secs)
    
    def get_coach_data(filename):
        try:
            with open(filename) as f:
                data = f.readline()
            return(data.strip().split(','))
        except IOError as ioerr:
            print('File error: ' + str(ioerr))
            return(None)
        
    sarah = get_coach_data('sarah2.txt')
    
    (sarah_name, sarah_dob) = sarah.pop(0), sarah.pop(0)
    
    print(sarah_name + "'s fastest times are: " +
            str(sorted(set([sanitize(t) for t in sarah]))[0:3]))
    

    这次加入了字典的做法

    字典将数据值与键关联:

    key   -->   value
    Name        "sarah sweeney"
    DOB         "2002-6-17"
    Times       "[2:58,2.58,2:39,2-25,2-55,2:54,2.18,2:55,2:55,2:22,2-21,2.22]"
    

    创建字典的方式可以是

    cleese = {} #大括号!!
    

    也可以是

    palin = dict()
    

    关联key和value的话是

    cleese['Name'] = 'John Cleese'  # 一个key 对应一个字符串
    

    或者

    cleese['Name'] = ['John Cleese','John Cleese1','John Cleese2','John Cleese3','John Cleese4'] #一个key对应一个list
    

    或者

    cleese = {'Name':'abc','Address':'asdasdasda'}  #注意是用冒号
    

    另外数据值与key关联后,需要访问数据值里面的某个数据项的话,可以是

    cleese['Name'][-1] 
    

    类似多维数组使用。

    代码改为

    #!/usr/bin/python
    # -*- coding: utf-8 -*-
    
    
    def sanitize(time_string):
            if '-' in time_string:
                    splitter = '-'
            elif ':' in time_string:
                    splitter = ':'
            else:
                    return(time_string)
            (mins,secs) = time_string.split(splitter)
            return (mins + '.' + secs)
    
    def get_coach_data(filename):
            try:
                    with open(filename) as f:
                            data = f.readline()
                    return(data.strip().split(','))
            except IOError as ioerr:
                    print('File error:' + str(ioerr))
                    return(None)
    
    sarah = get_coach_data('sarah2.txt')
    
    sarah_data={}
    sarah_data['Name'] = sarah.pop(0)   #根据数据结构,第一个数据是名字,第二个是生日,第二个之后是成绩,所以分别将相关数据赋值到字典里面。
    sarah_data['DOB'] = sarah.pop(0)
    sarah_data['Times'] = sarah
    
    print(sarah_data['Name'] + "'s fastest times are: " + str(sorted(set([sanitize(t) for t in sarah_data['Times']]))[0:3]))
    

    字典的方法优势在于合理使用数据结构。是否知道何时使用列表而何时使用字典,这正式从好的程序员中区分出优秀程序员的一个标准。
    字典其实也叫“映射”,“散列”,“关联数组”

    为了更加方便的处理多个人的成绩的数据,所以将字典数据转移到函数里面去,直接通过函数生成出字典,并返回需要的数据

    #!/usr/bin/python
    # -*- coding: utf-8 -*-
    
    
    def sanitize(time_string):
            if '-' in time_string:
                    splitter = '-'
            elif ':' in time_string:
                    splitter = ':'
            else:
                    return(time_string)
            (mins,secs) = time_string.split(splitter)
            return (mins + '.' + secs)
    
    def get_coach_data(filename):
            try:
                    with open(filename) as f:
                            data = f.readline()
                    templ = data.strip().split(',')
                    return({'Name':templ.pop(0),    #这里就是字典
                            'DOB':templ.pop(0),
                            'Times':str(sorted(set([sanitize(t) for t in templ]))[0:3])})
            except IOError as ioerr:
                    print('File error:' + str(ioerr))
                    return(None)
    
    sarah = get_coach_data('sarah2.txt')
    james = get_coach_data('james2.txt')
    
    print(sarah['Name'] + "'s fastest times are: " + sarah['Times'])
    

    这就是将代码和数据打包在一起。特定函数应用特定数据。

    更加正规的做法是建立类。

    类是面向对象oop编程模型的东西,类的概念在这里不详细描述。

    类可以

    1.降低复杂性
    2.方便维护和扩展
    

    python的类需要有一个self参数,这个参数是用来标识是属于哪个对象实例的

    例如:

    class Athlete:
        def __init__(self,value=0):
            self.thing = value      #定义这个类的属性thing
        def how_big(self)           #定义一个方法how_big
            return(len(self.thing))
    

    btw:init 是类的python固定实现方法,所以是必须的。

    你写的代码                   -->     python执行的代码
    d = Athlete("Holy Grail")           Athlete.__init__(d,"Holy Grail")
                                        |         |      |  
                                        类       方法    目标标识符 
                                        |         |     |
    d.how_big()                         Athlete.how_big(d)
    

    代码改为:

    def sanitize(time_string):
        if '-' in time_string:
            splitter = '-'
        elif ':' in time_string:
            splitter = ':'
        else:
            return(time_string)
        (mins, secs) = time_string.split(splitter)
        return(mins + '.' + secs)
    
    class Athlete:
        def __init__(self, a_name, a_dob=None, a_times=[]):
            self.name = a_name      #通过类的属性来定义name,dob和times
            self.dob = a_dob
            self.times = a_times
            
        def top3(self):
            return(sorted(set([sanitize(t) for t in self.times]))[0:3])
            
    def get_coach_data(filename):
        try:
            with open(filename) as f:
                data = f.readline()
            templ = data.strip().split(',')
            return(Athlete(templ.pop(0), templ.pop(0), templ))
        except IOError as ioerr:
            print('File error: ' + str(ioerr))
            return(None)
        
    james = get_coach_data('james2.txt')
    julie = get_coach_data('julie2.txt')
    mikey = get_coach_data('mikey2.txt')
    sarah = get_coach_data('sarah2.txt')
    
    print(james.name + "'s fastest times are: " + str(james.top3()))
    print(julie.name + "'s fastest times are: " + str(julie.top3()))
    print(mikey.name + "'s fastest times are: " + str(mikey.top3()))
    print(sarah.name + "'s fastest times are: " + str(sarah.top3()))
    

    科普:

    1.通过在各个对象的属性中保留原始数据,可以支持类扩展来满足将来的其他需求。如果处理数据并作为对象初始化代码的一部分,说明你已对程序员将如何使用这个类做出了假设,而日后这些假设肯定会对你造成障碍。

    在类里面增加一个灵活的增加成绩数据的函数

    可以是增加单个成绩,或是增加多个成绩
    单个成绩用add_time,传入的是字符串
    多个成绩是add_times,传入的是list

    以下是单个成绩的样例:

    #!/usr/bin/python
    # -*- coding: utf-8 -*-
    
    class Athlete:
            def __init__(self,a_name,a_dob=None,a_times=[]):
                    self.name = a_name
                    self.dob = a_dob
                    self.times = a_times
    
            def add_time(self,time_value):      #这里就是了。
                    self.times.append(time_value)
            def top3(self):
                    return (sorted(set([sanitize(t) for t in self.times]))[0:15])
            def add_times(self,list_of_times):
                    self.times.extend(list_of_times)
    
    def sanitize(time_string):
            if '-' in time_string:
                    splitter = '-'
            elif ':' in time_string:
                    splitter = ':'
            else:
                    return(time_string)
            (mins,secs) = time_string.split(splitter)
            return (mins + '.' + secs)
    
    def get_coach_data(filename):
            try:
                    with open(filename) as f:
                            data = f.readline()
                    templ = data.strip().split(',')
                    return (Athlete(templ.pop(0),templ.pop(0),templ))
            except IOError as ioerr:
                    print('File error:' + str(ioerr))
                    return(None)
    
    sarah = get_coach_data('sarah2.txt')
    
    sarah.add_time('2.88')      #这里调用
    print(sarah.name + "'s fastest times are: " + str(sarah.top3()))    #输出结果会改变
    

    观察到这个类有点像list,所以有重复制造车轮的嫌疑,并且功能单一,所以决定集成list类

    def sanitize(time_string):
        if '-' in time_string:
            splitter = '-'
        elif ':' in time_string:
            splitter = ':'
        else:
            return(time_string)
        (mins, secs) = time_string.split(splitter)
        return(mins + '.' + secs)
    
    class AthleteList(list):    #继续list类,所以这里要写list的名字
    
        def __init__(self, a_name, a_dob=None, a_times=[]):
            list.__init__([])   #这里需要初始化list类
            self.name = a_name
            self.dob = a_dob
            self.extend(a_times)    #因为集成list类了,所以这里可以直接使用list的extend方法
    
        def top3(self):
            return(sorted(set([sanitize(t) for t in self]))[0:3])
            
    def get_coach_data(filename):
        try:
            with open(filename) as f:
                data = f.readline()
            templ = data.strip().split(',')
            return(AthleteList(templ.pop(0), templ.pop(0), templ))
        except IOError as ioerr:
            print('File error: ' + str(ioerr))
            return(None)
        
    james = get_coach_data('james2.txt')
    julie = get_coach_data('julie2.txt')
    mikey = get_coach_data('mikey2.txt')
    sarah = get_coach_data('sarah2.txt')
    
    print(james.name + "'s fastest times are: " + str(james.top3()))
    print(julie.name + "'s fastest times are: " + str(julie.top3()))
    print(mikey.name + "'s fastest times are: " + str(mikey.top3()))
    print(sarah.name + "'s fastest times are: " + str(sarah.top3()))
    

    原文引用:http://www.godblessyuan.com/2015/05/03/head_first_python_chapter_6_learning/

    相关文章

      网友评论

          本文标题:head first python(第六章)–学习笔记

          本文链接:https://www.haomeiwen.com/subject/cogqqttx.html