Part 0. About Python
0.1 What is Python really?
- Python is an interpreted language.
- Python is dynamically typed, You can do things like x=111 and then x="I'm a string" without error
- Python is well suited to object orientated programming in that it allows the definition of classes along with composition and inheritance. Python does not have access specifiers (like C++'s public, private), the justification for this point is given as "we are all adults here"
- In Python, functions are first-class objects. This means that they can be assigned to variables, returned from other functions and passed into functions. Classes are also first class objects
0.2 Python and multi-threading. Is it a good idea? List some ways to get some Python code to run in a parallel way.
Python doesn't allow multi-threading in the truest sense of the word. It has a multi-threading package but if you want to multi-thread to speed your code up, then it's usually not a good idea to use it. Python has a construct called the Global Interpreter Lock (GIL). The GIL makes sure that only one of your 'threads' can execute at any one time. A thread acquires the GIL, does a little work, then passes the GIL onto the next thread. This happens very quickly so to the human eye it may seem like your threads are executing in parallel, but they are really just taking turns using the same CPU core. All this GIL passing adds overhead to execution. This means that if you want to make your code run faster then using the threading package often isn't a good idea.
There are reasons to use Python's threading package. If you want to run some things simultaneously, and efficiency is not a concern, then it's totally fine and convenient. Or if you are running code that needs to wait for something (like some IO) then it could make a lot of sense. But the threading library won't let you use extra CPU cores.
Multi-threading can be outsourced to the operating system (by doing multi-processing), some external application that calls your Python code (eg, Spark or Hadoop), or some code that your Python code calls (eg: you could have your Python code call a C function that does the expensive multi-threaded stuff).
0.3 Describe Python's garbage collection mechanism in brief.
- Python maintains a count of the number of references to each object in memory. If a reference count goes to zero then the associated object is no longer live and the memory allocated to that object can be freed up for something else
- occasionally things called "reference cycles" happen. The garbage collector periodically looks for these and cleans them up. An example would be if you have two objects o1 and o2 such that o1.x == o2 and o2.x == o1. If o1 and o2 are not referenced by anything else then they shouldn't be live. But each of them has a reference count of 1.
- Certain heuristics are used to speed up garbage collection. For example, recently created objects are more likely to be dead. As objects are created, the garbage collector assigns them to generations. Each object gets one generation, and younger generations are dealt with first.
This explanation is CPython specific.
Part 1. Types and Operations
1.1 The Dynamic Typing Interludes
def compare_id(x, y):
return id(x) == id(y)
a =[1,2,3]
b=a
print(compare_id(a,b))
x = [1, 2, 3]
y = x[:]
print(compare_id(x, y))
1.2 Numeric Types
1.3 String
1.4 Lists
# Checks whether a phrase is pangram, that is, if
# it contains all the letters of the alphabet.
def is_pangram( phrase ):
abec = [ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' ]
for a in phrase:
if a in abec:
i = abec.index( a )
abec.pop( i )
if len( abec ) == 0:
return True
return False
# Given a list of strings, return a list with the strings
# in sorted order, except group all the strings that begin with 'x' first.
# e.g. ['mix', 'xyz', 'apple', 'xanadu', 'aardvark'] yields
# ['xanadu', 'xyz', 'aardvark', 'apple', 'mix']
# Hint: this can be done by making 2 lists and sorting each of them
# before combining them.
def front_x(words):
# +++your code here+++
# LAB(begin solution)
# Put each word into the x_list or the other_list.
x_list = []
other_list = []
for w in words:
if w.startswith('x'):
x_list.append(w)
else:
other_list.append(w)
return sorted(x_list) + sorted(other_list)
# Given two lists sorted in increasing order, create and return a merged
# list of all the elements in sorted order. You may modify the passed in lists.
# Ideally, the solution should work in "linear" time, making a single
# pass of both lists.
def linear_merge(list1, list2):
# +++your code here+++
# LAB(begin solution)
result = []
# Look at the two lists so long as both are non-empty.
# Take whichever element [0] is smaller.
while len(list1) and len(list2):
if list1[0] < list2[0]:
result.append(list1.pop(0))
else:
result.append(list2.pop(0))
# Now tack on what's left
result.extend(list1)
result.extend(list2)
return result
1.5 Dictionaries
# Counts how many characters of the same letter there are in
# a string.
#
# ( 'aabbccddddd' ) -> { 'a': 2, 'b': 2, 'c': 2, d: 5 }
#
def char_freq( string ):
dict = {}
for a in string:
keys = dict.keys()
if a in keys:
dict[ a ] += 1
else:
dict[ a ] = 1
return dict
An anagram is a type of word play, the result of rearranging the letters of a word or phrase to produce a new word or phrase, using all the original letters exactly once; e.g., orchestra = carthorse. Using the word list at http://www.puzzlers.org/pub/wordlists/unixdict.txt, write a program that finds the sets of words that share the same characters that contain the most words in them.
def load_words( filename ):
with open( filename ) as f:
return [ re.findall( '\w+', f.read() ) ]
def find_anagrams( filename = 'data/words-43.md' ):
d, anagrams = defaultdict( list ), []
words = load_words( filename )
for word in words:
d[ ''.join( sorted( word ) ) ].append( word )
for k, v in d.iteritems():
if len( v ) > 1:
anagrams.append( v )
return anagrams
1.6 Tuples
# Given a list of non-empty tuples, return a list sorted in increasing
# order by the last element in each tuple.
# e.g. [(1, 7), (1, 3), (3, 4, 5), (2, 2)] yields
# [(2, 2), (1, 3), (3, 4, 5), (1, 7)]
# Hint: use a custom key= function to extract the last element form each tuple.
def sort_last(tuples):
# +++your code here+++
# LAB(begin solution)
return sorted(tuples, key=last)
婴儿姓名 Python 练习
社会保障中心为我们提供了以下数据,数据中记录了美国每年新生婴儿最受欢迎的名字。
请在名为“babynames”的文件夹下找到相关文件。观察这些 html 文件所包含信息。请思考如何能够从这些 html 文件中导出文件中的数据。
第一部分
打开“babynames.py”文件,编写你的 extract_names(filename) 函数。这个函数的输入应该为诸如 baby1990.html 这样的文件名,返回一个列表(list)。列表第一个元素应该为年份,随后为名字及其对应的排序。名字按英文字母顺序排列。例如[‘2006’,‘Aaliyah 91’,‘Abagail 895’,‘Aaron 57’, …]。修改你的 main()使得其调用你写的 extract_names(filename) 函数并打印返回结果,(main()中已经包含了对应变量处理语句,你可以直接在 command line 使用它)。文末有用于抓取年份和名字的正则表达式的提示,你如果遇到困难可以参考。需要注意的是,对于抓取普通网页,regular expression 不总能很好的解决问题。但是我们案例中提供的网页
有统一的格式,因此可以很好的完成工作。我们在这应该将男女名字同时处理。在有些年份,有的名字会出现不止一次,你可以选择其中的一个来作为排名依据。可选挑战:当你遇到这个情况的时候,试着选出较小的那个数。把整个程序拆分成不同的部分,在每一个部分完成后可以通过运行并打印结果来确保代码的正确。有经验的程序员经常采用这个技巧来逐步检查,逐步推进,而不是一口气将整个程序写完。把每一步结束之后的阶段性结果打印出来能帮助你思考如何在下一步处理这些结果。
Python 非常适用于这种分步编程方式。例如,首先尝试让你的程序提取并打印出年份,然后调用 sys.exit(0)。下列是我们推荐的将程序拆分开的方案:
• 从文件提取所有的文本信息并且打印
• 定位并提取年份,将其打印
• 提取名字和排名并打印
• 将名字和排名信息存入字典(dict)中
• 创建[年份,名字 排名,…]的列表(list)并打印
• 让 main()用上你前步获得的列表
之前,我们编写的函数直接将结果输入到了默认的输出设备。如果我们能让函数返回所提取的数据,那么函数的可用性将会提高。(你在开发过程中任然可以在函数内逐步打印你的阶段性结果)
让你的 main()调用你编写的 extract_names()。当你在 command line 运行你的python 程序时,对应每一个 command line 变量都应该输出一个如下格式的文本总
结。通过这个聪明的使用 join 的方法,你可以将之前要求的 list 变为我们希望的文本总结的格式:text = '\n'.join(mylist) + '\n'。
每一个文本总结应有以下格式
2006
Aaliyah 91
Aaron 57
Abagail 895
Abbey 695
Abbie 650
...
第二部分
下一步,我们希望在 command line 运行该程序的时候,如果命令中有 --summaryfile这样的 flag,程序对每一个“foo.html” 会将对应的文本总结写入到新建的“foo.html.summary” 文件中。
当上述的--summaryfile 功能实现后。通过在 command line 运行程序,并在程序中运用"./babynames.py --summaryfile baby*.html"代码,可以一次性生成所有的总结文本文件。(shell 会寻找所有符合"baby*.html"格式的文件名,并将所有文件名传入sys.argv 中)
当所有数据整理到对应的总结文本文件中后,你可以通过以下语句来观察这些名字排名随时间变化的趋势。
$ grep 'Trinity ' *.summary
$ grep 'Nick ' *.summary
$ grep 'Miguel ' *.summary
$ grep 'Emily ' *.summary
import sys
import re
"""Baby Names exercise
Define the extract_names() function below and change main()
to call it.
For writing regex, it's nice to include a copy of the target
text for inspiration.
Here's what the html looks like in the baby.html files:
...
<h3 align="center">Popularity in 1990</h3>
....
<tr align="right"><td>1</td><td>Michael</td><td>Jessica</td>
<tr align="right"><td>2</td><td>Christopher</td><td>Ashley</td>
<tr align="right"><td>3</td><td>Matthew</td><td>Brittany</td>
...
Suggested milestones for incremental development:
-Extract the year and print it
-Extract the names and rank numbers and just print them
-Get the names data into a dict and print it
-Build the [year, 'name rank', ... ] list and print it
-Fix main() to use the extract_names list
"""
def extract_names(filename):
"""
Given a file name for baby.html, returns a list starting with the year string
followed by the name-rank strings in alphabetical order.
['2006', 'Aaliyah 91', Aaron 57', 'Abagail 895', ' ...]
"""
# +++your code here+++
# LAB(begin solution)
# The list [year, name_and_rank, name_and_rank, ...] we'll eventually return.
names = []
# Open and read the file.
f = open(filename, 'rU')
text = f.read()
# Could process the file line-by-line, but regex on the whole text
# at once is even easier.
# Get the year.
year_match = re.search(r'Popularity\sin\s(\d\d\d\d)', text)
if not year_match:
# We didn't find a year, so we'll exit with an error message.
sys.stderr.write('Couldn\'t find the year!\n')
sys.exit(1)
year = year_match.group(1)
names.append(year)
# Extract all the data tuples with a findall()
# each tuple is: (rank, boy-name, girl-name)
tuples = re.findall(r'<td>(\d+)</td><td>(\w+)</td>\<td>(\w+)</td>', text)
#print tuples
# Store data into a dict using each name as a key and that
# name's rank number as the value.
# (if the name is already in there, don't add it, since
# this new rank will be bigger than the previous rank).
names_to_rank = {}
for rank_tuple in tuples:
(rank, boyname, girlname) = rank_tuple # unpack the tuple into 3 vars
if boyname not in names_to_rank:
names_to_rank[boyname] = rank
if girlname not in names_to_rank:
names_to_rank[girlname] = rank
# You can also write:
# for rank, boyname, girlname in tuples:
# ...
# To unpack the tuples inside a for-loop.
# Get the names, sorted in the right order
sorted_names = sorted(names_to_rank.keys())
# Build up result list, one element per line
for name in sorted_names:
names.append(name + " " + names_to_rank[name])
return names
# LAB(replace solution)
# return
# LAB(end solution)
def main():
# This command-line parsing code is provided.
# Make a list of command line arguments, omitting the [0] element
# which is the script itself.
args = sys.argv[1:]
if not args:
print 'usage: [--summaryfile] file [file ...]'
sys.exit(1)
# Notice the summary flag and remove it from args if it is present.
summary = False
if args[0] == '--summaryfile':
summary = True
del args[0]
# +++your code here+++
# For each filename, get the names, then either print the text output
# or write it to a summary file
# LAB(begin solution)
for filename in args:
names = extract_names(filename)
# Make text out of the whole list
text = '\n'.join(names)
if summary:
outf = open(filename + '.summary', 'w')
outf.write(text + '\n')
outf.close()
else:
print text
# LAB(end solution)
if __name__ == '__main__':
main()
1.7 Files
# Finds words that happen to be used only once in a text.
def find_hapax_legomenons( filename = 'data/the-dream.md' ):
dict, hapax_legomenons = {}, []
# Get words in the file
file = open( filename, 'r' )
words = re.findall( '\w+', file.read() )
for word in words:
keys = dict.keys()
word = word.lower()
if word in keys:
dict[ word ] += 1
else:
dict[ word ] = 1
for word in dict:
if dict[ word ] == 1:
hapax_legomenons.append( word )
return hapax_legomenons
# Given a text file, this function will create a new text file
# in which all the lines from the original file are numbered
# from 1 to n.
def copy_file_count_lines( filename = 'data/text.txt' ):
original = open( filename, 'r' )
# Create new file
new_file = open( 'data/output-37.md', 'w+' )
# Read file line by line
for line, content in enumerate( original ):
new_file.write( '%s %s' % ( line + 1, content ) )
with open("data/sample.csv", "r") as fin:
for line in fin:
print(line)
in_file = open("data/sample.csv", "r")
content = in_file.read()
type(content)
[line.split(",") for line in content.split("\n")]
in_file.close()
import csv
in_file = open("data/sample.csv", "r")
csv_reader = csv.reader(in_file)
data = list(csv_reader)
for line in csv_reader:
print("line #: {}, content: {}".format(csv_reader.line_num, line))
in_file.close()
out_file = open("data/out.tsv", "w")
out_writer = csv.writer(out_file, delimiter="\t")
out_writer.writerow(["july", "baidu", "ali", "tencent"])
out_writer.writerow(["fb", "goog", "aapl", "msft"])
out_writer.writerow([1.2, 3.5, "amazon", 5])
out_file.close()
import json
data = '{"name": "July", "salary": 999999, "title": "CEO", "manager": null}'
json_data = json.loads(data)
type(json_data)
json_data["name"]
in_file = open("data/sample.json", "r")
json_data = json.load(in_file)
in_file.close()
print(type(json_data))
print(json_data)
json_dumped = json.dumps(json_data)
print(type(json_dumped))
json.dump(json_data, open("data/out.json", "w"))
Part2. Statements and Syntax
2.1 Assignments, Expression, Prints
2.2 if
2.3 while and for loops
2.4 Iterations and Comprehensions
def map_words_v2( words ):
return [ len( word ) for word in words ]
2.5 The Documentation Interlude
Part3. Functions and Generators
3.1 Scopes
3.2 Arguments
3.3 Advanced Function Topics
# Given a list of numbers, this function returns the largest one,
# it does it using `reduce` function.
def max_in_list_v1( numbers ):
def compare( x, y ):
if y > x:
return y
return x
largest = reduce( compare, numbers )
return largest
# Maps a list of words into a list of integers representing each
# word length.
# It uses the `map()` higher-order-function.
def map_words_v1( words ):
return map( len, words )
# Using high-order-functions, this function receives a list of words,
# and return the longest one.
def find_longest_word_advanced( words ):
largest = max( words, key = len )
return len( largest )
# Takes a list of words and an integer and then return
# an array with all the words that are longer in length that
# the integer passed.
def filter_long_words_advanced( words, x ):
validate = lambda word: len( word ) >= x
filtered_words = filter( validate, words )
return filtered_words
# There are a fixed amount of words available for translatation.
# Uses `map()`.
# Sample:
#
# ( [ 'happy', 'new', 'year' ] ) -> [ 'happy', 'nya', 'år' ]
#
def translate_words( words ):
d = { 'all': 'alla', 'and': 'och', 'best': 'bäst', 'birthday': 'födelsedag', 'cake': 'kaka', 'celebrate': 'fira', 'christmas': 'jul',
'come': 'komma', 'dreams': 'drömmar', 'for': 'för', 'good': 'bra', 'happy': 'happy', 'hope': 'hopp', 'inviting': 'inbjudande', 'is': 'är',
'merry': 'merry', 'new': 'nya', 'thanks': 'tack', 'the': 'den', 'to': 'till', 'true': 'sant', 'us': 'oss', 'we': 'vi',
'wishes': 'önskemål', 'year': 'år', 'your': 'din' }
to_swedish = lambda word: d[ word ]
translated = map( to_swedish, words )
return translated
>>> x = [1, 2, 3]
>>> y = [4, 5, 6]
>>> zipped = zip(x, y)
>>> list(zipped)
[(1, 4), (2, 5), (3, 6)]
>>> x2, y2 = zip(*zip(x, y))
>>> x == list(x2) and y == list(y2)
True
3.4 Comprehensions and Generations
3.5 The Benchmarking Interlude
Part4. Modules and Packages
4.1 Module Coding Basics
4.2 Module Packages
4.3 Advanced Module Topics
4.4 Frequently used Modules
'''
The code in main will call your function with different values of n to see
how much unscrambled text in each word you need to understand it.
Example:
Words please, <cr> to exit: Numeric is a hedge fund operating out of offices in Boston
0: imeNucr si a deghe dfnu rntpigeao out of ifosfce in otnBso
1: Nmuerci is a hedeg fudn oantrgiep out of ofsfcie in Bontos
2: Nucermi is a heedg fudn opertaign out of ofiscfe in Botson
3: Numrcei is a hedge fund operantgi out of offseic in Boston
4: Numeicr is a hedge fund operingat out of offisec in Bostno
5: Numeric is a hedge fund operaigtn out of offices in Boston
6: Numeric is a hedge fund operatngi out of offices in Boston
7: Numeric is a hedge fund operating out of offices in Boston
8: Numeric is a hedge fund operating out of offices in Boston
So you need about 4 or so letters to understand the sentence.
HINT: The random module is useful, it has a function shuffle(sequence) that
return the sequence randomly shuffled.
'''
import random
def randomWords(words, n):
result =[]
for w in words:
w1 = list(w)
w2 = w1[:n]
w3 = w1[n:]
if w3:
random.shuffle(w3)
result.append(''.join(w2+w3))
return result
def main():
while True:
line = input('Words please, <cr> to exit:')
words = line.split()
if len(words) == 0:
break
max_len = max([len(w) for w in words])
for n in range(max_len):
print('%4d: %s'%(n, ' '.join(randomWords(words, n))))
if __name__ == '__main__':
main()
print('Bye, bye.')
A sentence splitter is a program capable of splitting a text into sentences. The standard set of heuristics for sentence splitting includes (but isn't limited to) the following rules:
Sentence boundaries occur at one of "." (periods), "?" or "!", except that
1. Periods followed by whitespace followed by a lower case letter are not sentence boundaries.
2. Periods followed by a digit with no intervening whitespace are not sentence boundaries.
3. Periods followed by whitespace and then an upper case letter, but preceded by any of a short list of titles are not sentence boundaries. Sample titles include Mr., Mrs., Dr., and so on.
4. Periods internal to a sequence of letters with no adjacent whitespace are not sentence boundaries (for example, www.aptex.com, or e.g).
5. Periods followed by certain kinds of punctuation (notably comma and more periods) are probably not sentence boundaries.
6. Your task here is to write a program that given the name of a text file is able to write its content with each sentence on a separate line. Test your program with the following short text:
Mr. Smith bought cheapsite.com for 1.5 million dollars, i.e. he paid a lot for it. Did he mind? Adam Jones Jr. thinks he didn't. In any case, this isn't true... Well, with a probability of .9 it isn't.
The result should be:
Mr. Smith bought cheapsite.com for 1.5 million dollars, i.e. he paid a lot for it. Did he mind? Adam Jones Jr. thinks he didn't. In any case, this isn't true... Well, with a probability of .9 it isn't.
import re
def split_sentences( filename = 'data/text-42.md' ):
file = open( filename )
text = file.read()
# Find and add a newline after every occurrence of a dot not preceded by ( `Mrs.`, `Mr.` or `Dr.` )
# and do followed by a space and an uppercase letter.
text = re.sub( r'\.(?<!Mrs.)(?<!Mr.)(?<!Dr.)(\s[A-Z])', r'.\n\1', text )
# Find and add a newline after every `?`
text = re.sub( r'\?', '?\n', text )
# Find and add a newline after every `!`
text = re.sub( r'\!', '!\n', text )
return text
Generate a string with N opening brackets ("[") and N closing brackets ("]"), in some arbitrary order.
Determine whether the generated string is balanced; that is, whether it consists entirely of pairs of opening/closing brackets (in that order), none of which mis-nest.
Examples:
[] OK ][ NOT OK
[][] OK ][][ NOT OK
[[][]] OK []][[] NOT OK
import re
def validate_brackets( string ):
string = re.sub( '\s+', '', string )
# Keep looping while there are ocurrences of `[]`.
while len( re.findall( r'\[]', string ) ) > 0:
string = re.sub( r'\[]', '', string )
if len( string ) == 0:
return True
return False
def analyze_rand_brackets():
length, string, spaces = random.randint( 1, 5 ) * 2, '', ''
brackets, openning, closing = '[]', 0, 0
for i in range( 0, length ):
rand_bracket = random.randint( 0, 1 )
string += brackets[ rand_bracket ]
for space in range( 1, 12 - len( string ) ):
spaces += ' '
feedback = 'OK' if validate_brackets( string ) else 'NOT OK'
print('{}{}{}'.format( string, spaces, feedback ))
特殊复制 Python 练习
copyspecial.py 程序输入一个及以上路径为变量。如果文件名中含有__w__的结构(w是一个或者多个字符),那么称该文件为特殊文件。main 中已包含了处理commandline 变量的语句,但是你要自己完成剩下部分。按以要求完成以下函数,并让你的main 调用他们。
以下为我们推荐的一些函数及功能:
• get_special_paths(dir) – 返回一个包含指定文件夹下特殊文件绝对路径的列表
• copy_to(paths, dir) – 把一个路径下的所有文件拷贝到另一个路径
• zip_to(paths, zippath) – 把一个路径下的所有文件压缩打包到另一个路径
A 部分:处理文件路径
将所有给定路径下的特殊文件的绝对路径构建成一个列表,并打印出来,每个路一
行(命令语句后的“.”为一个参数,表示当前目录)。
$ ./copyspecial.py .
/Users/nparlante/pycourse/day2/xyz__hello__.txt
/Users/nparlante/pycourse/day2/zz__something__.jpg
我们在此假定不同路径下的所有的文件名唯一。可选挑战:你可以在代码中加入一个验证此假定的环节,如果不符合,返回错误信息。
B 部分,文件拷贝
如果 command line 中出现了"--todir dir",不要打印任何内容,而是将特殊文件拷贝到所给的路径。(在 Python 中用" shutil” 来拷贝文件。)
$ ./copyspecial.py --todir /tmp/fooby .
$ ls /tmp/foobyxyz__hello__.txt zz__something__.jpg
C 部分: 调用外部程序
如果 command line 中出现了"-- tozip zipfile ",运行"zip -j zipfile <list all the files>"。这会新建一个包含所有文件的压缩文件。之后再答应出你所进行的操作以保证正确。(windows 用户可在此下载免费开源 zip 程序 www.info-zip.org)
$ ./copyspecial.py --tozip tmp.zip .
Command I'm going to do:zip -j tmp.zip
/Users/nparlante/pycourse/day2/xyz__hello__.txt
/Users/nparlante/pycourse/day2/zz__something__.jpg
如果子进程因错误而退出,将错误信息打印并退出程序。通过要求把文件压缩到一个不存在的路径来测试你的错误处理环节。
$ ./copyspecial.py --tozip /no/way.zip .
Command I'm going to do:zip -j /no/way.zip
/Users/nparlante/pycourse/day2/xyz__hello__.txt
/Users/nparlante/pycourse/day2/zz__something__.jpg
zip I/O error: No such file or directory
zip error: Could not create output file (/no/way.zip)
import sys
import re
import os
import shutil
import zipfile
"""Copy Special exercise
"""
# +++your code here+++
# Write functions and modify main() to call them
def get_special_paths(dir):
result = []
paths = os.listdir(dir)
for fname in paths:
match = re.search(r'__(\w+)__', fname)
if match:
result.append(os.path.abspath(os.path.join(dir, fname)))
return result
def copy_to(paths, to_dir):
if not os.path.exists(to_dir):
os.mkdir(to_dir)
for path in paths:
fname = os.path.basename(path)
shutil.copy(path, os.path.join(to_dir, fname))
def zip_to(paths, zippath):
zip = zipfile.ZipFile(zippath, 'w')
for file in paths:
zip.write(file)
zip.close()
def main():
# This basic command line argument parsing code is provided.
# Add code to call your functions below.
# Make a list of command line arguments, omitting the [0] element
# which is the script itself.
args = sys.argv[1:]
if not args:
print( "usage: [--todir dir][--tozip zipfile] dir [dir ...]")
sys.exit(1)
# todir and tozip are either set from command line
# or left as the empty string.
# The args array is left just containing the dirs.
todir = ''
if args[0] == '--todir':
todir = args[1]
del args[0:2]
tozip = ''
if args[0] == '--tozip':
tozip = args[1]
del args[0:2]
if len(args) == 0:
print( "error: must specify one or more dirs")
sys.exit(1)
paths = []
for dirname in args:
paths.extend(get_special_paths(dirname))
if todir:
copy_to(paths, todir)
elif tozip:
zip_to(paths, tozip)
else:
print('\n'.join(paths))
# +++your code here+++
# Call your functions
if __name__ == "__main__":
main()
Part5. Classes and OOP
5.1 Class Coding Basics
5.2 Class Coding Details
5.3 Operator Overloading
5.4 Designing with Classes
# File employee.py
class Employee(object):
def __init__(self, name, ID, title, salary, manager = None):
self.name = name
self.ID = ID
self. title = title
self. salary = salary
self.manager = manager
def get_info(self):
return " Empolyee name:{}, title:{}, salary:{}, manager:({})".format(self.name,
self.title, self.salary, self.manager.get_info() if self.manager is not None else "")
# define ==
def __eq__(self, other):
return self.ID == other.ID
# File company.py
class Company(object):
def __init__(self, name, employees = []):
self.name = name
self.employees = employees
def hire(self, employee):
if not employee in self.employees:
self.employees.append(employee)
def fire(self, employee):
if employee in self.employees:
self.employees.remove(employee)
def get_info(self):
res = "Company:{}, employees:".format(self.name)
for employee in self.employees:
res += ", {}".format(employee.get_info())
return res
# File main.py
from employee import Employee
from company import *
if __name__ == "__main__":
july = Employee("July", 1, "CEO", 999999)
print(july.get_info())
zewei = Employee("Zewei", 2, "Lecturer", 1, july)
print(zewei.get_info())
c = Company("Julyedu")
c.hire(july)
c.hire(zewei)
han = Employee("Han Xiaoyang", 3, "Leturer", 1000000, july)
c.hire(han)
print(c.get_info())
print("Firing zewei")
c.fire(zewei)
print(c.get_info())
5.5 Advanced Class Topics
from abc import ABC, abstractmethod
class Person(ABC):
@abstractmethod
def __init__(self, name, ID):
self.name = name
self.ID = ID
@abstractmethod
def get_info(self):
return "name:{}".format(self.name)
#tongjun = Person("Tongjun", 11)
#print(tongjun.get_info())
class Student(Person):
def __init__(self, name, ID, level = 0):
super().__init__(name, ID)
self.level = level
def get_info(self):
return "{}, level:{}".format(super().get_info(), self.level)
def take_exam(self, grade):
if grade.upper() in ["A", "B", "C"]:
self.level += 1
return self.level
def graduate(self):
print(self.get_info())
if self.level >= 12:
print("Congratulations! You've graduated from Julyedu")
return True
else:
print("Sorry. you need to pass {} extra exams!".format(12-self.level))
return False
hongyu = Student("Hongyu", 10, 3)
print(hongyu.get_info())
hongyu.graduate()
hongyu.take_exam("A")
hongyu.take_exam("A")
hongyu.take_exam("B")
hongyu.take_exam("A")
hongyu.take_exam("A")
hongyu.take_exam("A")
hongyu.take_exam("B")
hongyu.take_exam("A")
hongyu.take_exam("C")
print(hongyu.get_info())
hongyu.graduate()