Bundling code with data
it is important to match your data structure choice to your data.
Use a "dictionary" to associate data: Keys and Values
Python dictionary name in other languages:
- mapping
- a hash
- associative array
Create a dictionary (2 ways):
- clesse={}
- palin=dict()
Add data to dictionary:
cleese ['Name']='John Cleese'
cleese['Occupations']=['actor','comedian','writer','film producer']
Python dictionary does not maintain insertion order
Keeping your code and its data together is good, but how?
Bundle your code and its data in a class
Using a class helps reduce complexity.
Reduced complexity means fewer bugs.
Fewer bugs means more maintainable code.
Define a class
Your code is often referred to as the class’s methods
Your data is often referred to as its attributes.
Instantiated data objects are often referred to as instances.
Use class to define classes
Python uses class to create objects. Every defined class has a special method
called __init__()
Creating object instances
variables = Class()
The importance of self
a = Athlete() --->Athlete().__init__(a)----> def __init__(self)def __init__(self):# The code to initialize an "Athlete" object.
Class code is designed to be shared among all of the object instances:
the methods are shared, the attributes are not. The self argument helps identify which object instance’s data to work on.
Every method’s first argument is self
Don't use external method to modify attributes in your class
🙂sarah.add_time('1.23')
🙁sarah.times.append('1.23')
By defining your own API with add_time() and add_times(), you leave open the possibility that the way the data is stored within your class can change in the future. Exposing the internals of your class’s implementation and expecting programmers to exploit it breaks this fundamental ideal in a very big way.
Inherit from Python’s built-in list
Custom Class vs Inherited Class
---Vocabulary---
scribbled all over your code: 圈出你需要改正的地方
Here are a few more...:还要改一点...
Rather than building the dictionary as you go along, why not do it all in one go?: 能合并吗?
Instantiate: 实例化
encapsulate: to place in or as if in a capsule. to summarize or condense. 封装
your ~ might just come back to bite you:你的~以后会有麻烦
it’s a breeze to...:这很容易...
in a big way...很大程度上
reinventing the wheel... in a needless. 闭门造车轮
is ~in disguise ... ~实际就是
Wouldn't it be dreamy if there were a way ~... 如果~那该多好
be in line for : If you are in line for something, it is likely to happen to you or you are likely to obtain it.将要
build every thing from the ground up (from the most elementary level):从零开始
eons ago:很久很久以前
live to code:写代码为生
Questions
-
why inherited Class can use "self" without time in top3() method?
-
return str(sorted(set(sanitize(t) for t in self))[0:3])
-
Why need initialise list in ListAthlete?
list.__init__([])
Code:
1. Origional code
def sanitize(time_string):
"""Sanitize the dirt format, keep all time format as mins.secs
:param time_string: time string from coach data file
:return: formated 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):
"""
Open data file
:param filename: data file name
:return: None
"""
try:
with open(filename) as f:
data = f.readline()
return data.strip().split(',')
except IOError as ioerr:
print('File error: ' + str(ioerr))
return None
2. Use Dictionary
def sanitize(time_string):
"""Sanitize the dirt format, keep all time format as mins.secs
:param time_string: time string from coach data file
:return: formated 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):
"""
read data file, split the data into dictionary and sort out
:param filename: data file name
:return: None
"""
try:
with open(filename) as f:
data = f.readline()
athelet_list = data.strip().split(',')
return ({'name': athelet_list.pop(0),
'dob': athelet_list.pop(0),
'Times': str(sorted(set(sanitize(t) for t in athelet_list))[0:5])})
except IOError as ioerr:
print('File error: ' + str(ioerr))
return None
sarah = get_coach_data('sarah2.txt')
print(sarah['name']+"'s fastest times are: "+sarah['Times'])
3. Use custom Class
def sanitize(time_string):
"""Sanitize the dirt format, keep all time format as mins.secs
:param time_string: time string from coach data file
:return: formated 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
self.dob = a_dob
self.times = a_times
def top3(self):
return str(sorted(set(sanitize(t) for t in self.times))[0:3])
def add_time(self, time_value):
self.times.append(time_value)
def add_times(self, list_of_times):
self.times.extend(list_of_times)
def get_coach_data(filename):
"""
read data file, split the data into dictionary and sort out
:param filename: data file name
:return: None
"""
try:
with open(filename) as f:
data = f.readline()
athelet_list = data.strip().split(',')
return Athlete(athelet_list.pop(0), athelet_list.pop(0),athelet_list)
except IOError as ioerr:
print('File error: ' + str(ioerr))
return None
sarah = get_coach_data('sarah2.txt')
print(sarah.name + "'s fastest times are: " + sarah.top3())
vera = Athlete('Vera Vi')
vera.add_time('1.31')
print(vera.top3())
vera.add_times(['2.22', '1-21', '2:22', '2-32', '1.32'])
print(vera.top3())
4. Inherited Class
def sanitize(time_string):
"""Sanitize the dirt format, keep all time format as mins.secs
:param time_string: time string from coach data file
:return: formated 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(list):
def __init__(self, a_name, a_dob=None, a_times=[]):
list.__init__([])
self.name = a_name
self.dob = a_dob
self.extend(a_times)
def top3(self):
return str(sorted(set(sanitize(t) for t in self))[0:3])
def get_coach_data(filename):
"""
read data file, split the data into dictionary and sort out
:param filename: data file name
:return: None
"""
try:
with open(filename) as f:
data = f.readline()
athelet_list = data.strip().split(',')
return Athlete(athelet_list.pop(0), athelet_list.pop(0),athelet_list)
except IOError as ioerr:
print('File error: ' + str(ioerr))
return None
sarah = get_coach_data('sarah2.txt')
print(sarah.name + "'s fastest times are: " + sarah.top3())
vera = Athlete('Vera Vi')
vera.append('1.31')
print(vera.top3())
vera.extend(['2.22', '1-21', '2:22', '2-32', '1.32'])
print(vera.top3())