## Review

### 1. Python in 4 sentences

1. Python in Four Sentences:
1. Names (in namespaces) are bound to objects.
2. Everything that Python computes with is an object.
3. Every object has its own namespace. 函数也能有attribute (a dictionary that binds its internal names to other objects)
4. Python has rules about how things work
2. Objects are the fundamental unit with which Python computes:
1. We can compute with int objects (instance objects from the int class) by using operators
2. We can compute with function objects by calling them
3. we can also pass functions as arguments to functions and return functions as results from functions
4. We can compute with module objects by importing them
1. import random
1. The name random is bound to the random moudle object
2. from random import randint
1. The name randint is bound to the function object ‘randint’

### 2. Binding

1. The process of making a name refer to a value: e.g., x = 1 binds the name x to the value 1
2. In Python, every data instance, module, function, and class is an object that has a dictionary that stores its namespace: all its internal binding
3. How to draw binding operation
4. writing del x inside module m would remove x and its box from m’s namspace/dictionary
1. the del command in Python (e.g., del name) removes a name from the current namespace/dictionary of the object in which name is bound
2. If there was no name x in this module, Python raises an NameError exception.
1. (不能del print，因为print在builtin moudle而不是在script里面定义的，除非有定义新print)
2. 但是可以del builtin.print，只要qualify其module名就行了
5. is and ==
1. the "is" operator in Python determines whether two references refer to the same object
2. the == operator determines whether two references refer to objects that store the same internal state.

### 3. Statements vs Expressions

1. In Python the basic unit of code is a statement: statements are built from
1. expressions (like a boolean expression in an if statement) and
2. other statements (like block statements inside an if statement).
2. 区别：
1. Statements are executed to cause an effect.
2. Expressions are evaluated to compute a result
3. The print function is a bit strange:
1. We call if for an effect (putting characters in the Console window)
2. but like every function, also returns a value: when print is called successfully (doesn’t raise any exceptions) it returns the value None
4. Control structures (even simple sequential ones, like blocks) are considered to be statements in Python
1. y = (0 if x == None else 1)

### 4. None

1. None is a value (object/instance) of NoneType
1. it is the only value of that type
2. a Python function that terminates without executing a return statement automatically returns the value None
1. If None shows up as an unexpected result printed in your code or more likely in a raised exception,
2. look for some function whose return value you FORGOT to specify explicitly

### 5. pass

1. semantically, it means "do nothing".
2. we might use pass as a placeholder until we write the actual statement we need.

### 6. Importing: 5 forms

1. "import module-name" form: one or more modules, optionally renaming each：
1. import module-name{,module-name}
2. import module-name [as alt-name] {,module-name [as alt-name]}
3. The "import module-name" forms import the names of modules (not their attribute names).
1. (1)bind each module-name to the object representing that imported module-name.
2. (2)bind each alt-name to the object representing its preceding imported module-name.
4. Using a module name, we can refer to its attributes using periods, such as by module-name.attribute-name
2. "from module-name import" form: one or mor attributes, optionally renaming each:
• (3) from module-name import attr-name{,attr-name}
• (4) from module-name import attr-name [as alt-name] {,attr-name [as alt-name]}
• (5) from module-name import *
• The "from module-name import" forms import some/all attribute names defined/bound inside module-name
• (3) bind each attr-name to the object bound to that attr-name in module-name
• (4) bind each alt-name to the object bound to the preceding attr-name in module-name
• (5) bind each name that is bound in module-name to the same object it is bound to in module-name.
3. Import (like an assignment, and a def, and a class definition) creates a name (if that name is not already in the namespace) and binds it to an object
1. the "import module-name" form binds names to module objects
1. 可以先定义 x=12 然后 import x，此时x为导入的模组
2. the "from module-name import" form binds names to objects
4. The key idea as to which kind of import to use is to make it easy to refer to a name but not pollute the name space of the module doing the importing with too many names
1. （use the "import module-name" form (1)）If （a lot of different names in the imported module are to be used）, or （we want to make it clear when an attribute name in another module is used）, and then qualify the names when used
2. （use an abbreviaton by importing using an alt-name (2) ） If （the imported module-name is too large for using repeatedly）
3. If only one name (or a few names) are to be used from a module, use the form (3):

### 7. Directly iterating over values in a list vs. Using a range to iterate over indexes of values in a list

1. Often we want to iterate over all the values in a list (alist) but don’t need to know/use their indexes
2. goody.irange goody.frange

### 8. Arguments and Parameters (and Binding): Terminology (much more details later)

1. Whenever we DEFINE a function (and define methods in classes), we specify the names of its PARAMETERS in its header (in parentheses, separated by commas).
2. Whenever we CALL a function we specify the values of its ARGUMENTS (also in parentheses, separated by commas).
3. function calls happen in three steps:
1. evaluate the arguments
2. bind the argument values (objects) to the parameter names
3. execute the body of the function, using the values bound to the parameter names; so parameters are names inside the name-space of the function, along with any local variables the function defines.
4. Sometimes we can use the parameter of a function as an argument to another function call inside its body
5. Parameters are always names. Arguments are expressions that evaluate to objects.

### 9. Function calls … always include () how we can pass a function as an argument to another function

1. Any time a reference to an object is followed by (…) it means to perform a function call on that object
1. Some objects will raise an exception if they do not support function calls 3() or ‘abc'()
1. TypeError : ‘str’ object is not callable
2. Note that each def defines the name of a function and binds that name to the function object that follows it
3. 可以f=某function，来bind函数
1. 此时f is 某function == True
4. 甚至可以 for f in [函数1,函数2,函数3]: print(f(5))
5. Using the same logic, we could also write a dictionary whose keys are strings and whose values are function objects, and then use a string as a key needed to retrieve and call its associated function object.
fs = {‘x2’ : double, ‘x3’ : triple, ‘x10’ : times10}
print( fs[‘x3’](5) )
6. def is really just a special syntax for creating a name f and binding it to a new function object
7. functions are objects

### 10. Scope: Global and Local Names (generalized in the next section)

1. The topic of SCOPE concerns the visibility of variable names: when a name is written in Python code, to what definition of that name does it refer
2. global vs local
1. Names defined in a module are global definitions
2. names defined in a function (including its parameters, and later names defined in a class) are local definitions
3. In a module, we can refer to global names, but not any local names inside the functions/class that are define there
4. In functions we can refer both to their local names or to global names
3. Python Rules:
1. A name used in a module is global
2. A name used in a function is global if that name is explicitly declared global (e.g., global x) PRIOR to its use in the function
3. A name used in a function is nonlocal/enclosing if that name is explicitly declared nonlocal (e.g., nonlocal x) prior to its use in that function
4. A name used in a function is local
1. a) that name is a parameter in that function, or
2. b) that name is bound anywhere in that function (and is neither declared global nor nonlocal)
5. Otherwise, a name is LEGB (if it is none of the above) NOTE: an LEGB name can NEVER be bound in a function (if it is bound, it must be declared global, or nonlocal, or will be local by 4a or 4b). So LEGB names are ONLY LOOKED-UP.
4. We can change the value in the global name x by using a "global" declaration before x is used in function: global x
1. This declaration means that x should always be treated as a global name inside this function (whether it is examined or bound to an object, or both) by rule 2
2. 如果在调用x之后global x则会 SyntaxError: name ‘x’ is used prior to global declaration
1. 与UnboundedError区分
5. when Python creates an function object, it first scans the whole function to determine whether a name refers to a global name or a local name, looking for global declarations and bindings to make this determination
6. we can always lookup (find the value of, evaluate) a global name inside a function to find its value without doing anything special, but if we want to (re)bind the global name to a new value inside the function, we must declare the name global somewhere in the function (before its first use).
7. BUT if a function must (re)bind a global name either
1. the name should be declared global (so it can be examined/changed), or
2. the function should be called like global-name = f(…)

### 11. Generalizing Scope: Local, Enclosing, Global, and Builtins LEGB

1. Here are the corresponding rules for looking-up/binding all these names.
• A+B) When a name is global,
1. Python LOOKS UP that name, in order,
2. b) in the Builtins scope (in the builtins module); and if not found
3. c) raises NameError
2. Python BINDS that name in the Global scope
• C) When a name is nonlocal/enclosing, Python looks for the name in the scope of the function enclosing it (if there is one); if it doesn’t find it there, it looks in the scope of the function enclosing the enclosing function (if there is one). This process continues outward until it finds the name and then uses the name in that scope. If it cannot find the name and reaches the global scope, Python raises a SyntaxError exception: no binding for nonlocal … found
• D) When a name is local, Python looks-up/binds that name in the local scope.
• E) When a name is LEGB, Python looks for the name, in order,
2. in any of the Enclosing scopes (see rules in C); and if not found
4. in the Builtins scope(in the builtins module); and if not found
5. raises NameError

### 12. Functions vs Methods: The Fundamental Equation of Object-Oriented Programming

1. "The Fundamental Equation of Object-Oriented Programming." (FEOOP) : o.m(…) = type(o).m(o,…)
• 1) type(o) returns a reference to the class object o was constructed from.
• 2) .m means call the function m declared inside that class: look for
def m(self,…): …. in the class
• 3) pass o as the first argument to m: recall, that when defining methods in classes we write def m(self, ….); where does the argument matching the self parameter come from? It comes from the object o in calls like o.m(…)
• This equation is not compeletely true.

### 13. lambda

1. A lambda represents a special function object.
2. we can just use a (lambda:) after the word lambda comes (its parameters separated by commas), then a colon followed by (a single EXPRESSION that computes the value of a lambda)
1. no "return" is needed
2. the function cannot include control structures/statments, not even a sequence of statements
3. A lambda produces an UNNAMED function object

### 14. Parallel/Tuple/List Assignment (aka sequence unpacking)

1. To do any parallel assignment, Python
• (a) first computes all the values of the expressions/objects on the right (1 and 2 from the top)
• (b) second binds each name on the left (x then y) to these computed values/objects (binds x to 2, then bind y to 1)
2. This is also called "sequence unpacking assignment": both tuples and list are considered kinds of sequences
1. Note that x,y = 1,2,3 and x,y,z = 1,2 would both raise ValueError exceptions, because there are different numbers of names and values to bind to them
3. l,m,(n,o) = (1, 2, [3,4])
1. print(l,m,n,o)
2. prints: 1 2 3 4
4. a,*b,c = [1,2,3,4,5]
1. print(a,b,c)
2. 1 [2, 3, 4] 5
• can preface any name; the name is bound to a sequence of any number of values
1. We could not write a,b,c = [1,2,3,4,5]
2. 可以l,(m,n),o = (1, [‘a’,’b’,’c’], 2, 3,4)
3. 1 [‘a’, ‘b’] c [2, 3, 4]

### 15. Iterable

1. When we specify that an argument of a function must be iterable, it might be one of the standard data structures in Python: str, list, tuple, set, dict.
2. iterable: we can iterate over the values they contain by using a simple for loop.
3. But we will learn other Python features (classes and generators) that are also iterable:
1. The difference is, that for standard Python data structures we can call the "len" function on them and index them […];
4. we can always use a comprehension (dicussed later in this lecture) to transform any iterable into a list or tuple of its values

### 16. sort (a list method)/sorted (a function): and their "key"/"reverse" parameters

1. Difference:
1. sort is a method defined on arguments that are LIST objects:
1. it returns None
2. but MUTATES its list argument to be in some specified order
2. sorted is a function defined on arguments that are any ITERABLE object:
1. it returns a LIST of its argument’s values
2. The argument itself is NOT MUTATED
3. the sort method can be applied only to lists, but the sorted function can be applied to any iterable
2. the sort method is defined only on LIST class objects, not DICT class objects.
3. How Python sorted:
1. Python executes the sorted function by creating a temporary list from all the values produced by the iterable,
2. then sorts that temporary list,
3. and then returns the sorted list.

### 17. How to use a key parameter to sort arbitrarily:

1. What sort is doing is comparing each value in the list to the others using the standard meaning of <. .
2. We can specify a "key" function that computes a key value for every value in what is being sorted, and the COMPUTED KEY VALUES ARE USED FOR COMPARISON
3. by writing "key=by_vote_count" Python didn’t CALL the by_vote_count function (there are no parentheses) it just passed its associated function object to the key parameter in the sorted function
4. 如果两个object通过key函数返回的结果相同，那么这两个objects将会按一定的unspecified规律排序，但是这个规律是固定的。
5. rather than define this simple by_vote_count function, we can use a lambda instead, and write the following
6. Another way to sort in reverse order (for integers) is to use the "negation" trick illustrated below (and omit reverse=True).
1. for c,v in sorted(votes, key=(lambda t : -t[1]) ):
2. 这个方法再(降序int字母表顺序str)排(int,str)时很有效，因为我们不能用reverse，因为一个降序一个升序
3. Our ability to use this "negation trick" works in SOME cases, but unfortunately NOT IN ALL cases

### 18. Arbitrary sorting: multiple calls to sorted with "stable" sorting

1. Python’s sorted function (and sort method) are "stable". This property means that "equal" values (decided naturally, or with the key function supplied) keep their same "relative" order (left-to-right positions) in the data being sorted.
2. sorted( sorted(db, key=(lambda x : x[0])), key=(lambda x : x[1]), reverse=True )
1. == sorted( sorted(db), key=(lambda x : x[1]), reverse = True )
3. if we can call sorted once, using a complicated key and reverse, that is the preferred approach
4. if we are unable to specify a single key function and reverse that do the job, we can always call sorted multiple times, using multiple key functions and multiple reverses, sometimes relying on the "stability" property to achieve our sorting goal

### 19. The print function

1. print(‘Your answer of {} is too high\nThis is on the next line’.format(10))
print(‘Your answer of {x} is too high\nThis is on the next line’.format(x=10))
2. print(f’Your answer of {x} is too high\nThis is on the next line’)
1. {}内是一个expression:比如一个variable或者算式

1. index
2. slicing

### 21. Conditional statement vs. Conditional expression

1. The form of a conditional expression is
1. resultT if test else resultF
1. 这是一个expression一个expression
2. Note that conditional expressions REQUIRE using BOTH THE if AND else KEYWORDS,
2. 可以结合f string
1. print(f"{x} is {‘even’ if x%2 == 0 else ‘odd’}")

### 22. The else: block-else option in for/while loops

1. for和while块后可以加else块，该块会在循环正常结束后使用

### 23. Argument/Parameter Matching (leaves out **kargs, discussed later)

1. Arguments
1. positional argument: an argument NOT preceded by the name= option
2. named argument: an argument preceded by the name= option
2. Parameters
1. name-only parameter :a parameter not followed by =default argument value
2. default-argument parameter:a parameter followed by =default argument value
3. When Python calls a function, it must define every parameter name in the function’s header
4. three criteria: positions, parameter names, and default arguments for parameter names.
5. Rule:
1. M1. Match positional argument values in the call sequentially to the parameters named in the header’s corresponding positions (both name-only and default-argument parameters are OK to match). Stop when reaching any named argument in the call, or the * parameter (if any) in the header.
2. M2. If matching a * parameter in the header, match all remaining positional argument values to it. Python creates a tuple that stores all these arguments. The parameter name (typically args) is bound to this tuple.
3. M3. Match named-argument values in the call to their like-named parameters in the header (both name-only and default-argument parameters are OK).
4. M4. Match any remaining default-argument parameters in the header (unmatched by rules M1 and M3) with their specified default argument values.
5. M5. Exceptions: If at any time
1. (a) an argument cannot match a parameter (e.g., a positional-argument follows a named-argument)
2. or (b) a parameter is matched multiple times by arguments;
3. or if at the end of the process (c) any parameter has not been matched
4. or (d) if a named-argument does not match the name of a parameter, raise an exception:
1. SyntaxError for (a) and
2. TypeError for (b), (c), and (d). These exceptions report that the function call does not correctly match its header by these rules.

## Constructors operating on Iterable values to Construct Data

### 24. List,tuple,set

1. Python’s "for" loops allow us to iterate through all the components of any iterable data
2. l = list (‘radar’) then l is [‘r’, ‘a’, ‘d’, ‘a’, ‘r’]
t = tuple(‘radar’) then t is (‘r’, ‘a’, ‘d’, ‘a’, ‘r’
s = set (‘radar’) then s is {‘a’, ‘r’, ‘d’} or {‘d’, ‘r’, ‘a’} or …
3. since tuples/sets are iterable, we can also compute a list from a list, a list from a a tuple, or a list from a set
1. note that l is list(l) is False, but l == list(l) is True
2. Likewise we could create a tuple from a list/set, or a set from a list/tuple

### 25. Dictionary Constructors:

1. there are actually THREE ways to iterate through dictionaries: by keys, by values, and by items
2. d = dict(a=1,b=2,c=3,d=4,e=5) # the same as d = {‘a’:1,’b’:2,’c’:3,’d’:4,’e’:5}
1. list(d.keys ()) is like [‘c’, ‘b’, ‘a’, ‘e’, ‘d’]
2. list(d.values()) is like [3, 2, 1, 5, 4]
3. list(d.items ()) is like [(‘c’, 3), (‘b’, 2), (‘a’, 1), (‘e’, 5), (‘d’, 4)]
3. sets and dicts are NOT ORDERED
4. the keys in a dict are always unique, but there might be duplicates among the values
5. One way to construct a dict is to give it an iterable, where each value is either a 2-tuple or 2-list
1. a key followed by its associated value
2. or, even (a tuple that has a mixture of 2-tuples and 2-lists in it)
1. d = dict( ((‘a’, 1), [‘b’, 2], (‘c’, 3), [‘d’, 4], (‘e’, 5)) )
3. or even (a set of 2-tuples; we cannot have a set of 2-list (see hashable below)
d = dict( {(‘a’, 1), (‘b’, 2), (‘c’, 3), (‘d’, 4), (‘e’, 5)}
6. We can also combine the two forms writing d = dict( {(‘a’, 1), (‘b’, 2), (‘c’, 3), (‘d’, 4), (‘e’, 5)}, f=6, g=7)
7. if we wanted to construct a dict using the keys/values in another dict, here are two easy ways to do it:
1. d_copy = dict(d)
2. d_copy = dict(d.items())
8. 用constructor可以相当于deepcopy

### 26. Sharing/Copying: is vs. ==

1. Note that if we mutate a shared object, both names "see" the change: both are bound to the same object which has mutated
2. But if they refer to different copies of an object, only one name "sees" the change.
3. copy()
1. return type(x)(x)
4. 画图2

### 27. Hashable vs. Mutable and how to Change Things:

1. Python uses the term Hashable, which has the same meaning as Immutable
1. hashable and mutable are OPPOSITES
2. hashable means the same as immutable
3. unhashalble means the same as mutable
2. Hashable/immutable: numeric values, strings, tuples containing hashable/immutable data, frozenset
3. mutable/unhashable: list, sets, dict
4. a tuple storing hashable/immutable values is hashable/immutable, but a tuple storing unhashable/mutable values is unhashable/mutable
5. A frozenset can do everything that a set can do, but doesn’t allow any mutator methods to be called
1. The constructor for a frozenset is frozenset(…) not {}
6. The function hash takes an argument that is hashable and returns an int
1. (otherwise it raises TypeError, with a message about a value from an unhashable type)

### 28. unique objects

1. Small integer objects are unique in Python.
1. Python allocates only one object for each small int
1. x,y=1 => x is y ==True
2. 节省空间
2. List的话就不是 x,y=[‘a’],[‘a’] => x is y ==False
3. String
1. Whether "is" operating on two strings with the same characters is True depends on
1. the length of the strings and
2. whether the string was computed or entered by the user in the console.

## Comprehensions: list, tuple, set, dict

### 29. List, Tuple, Set Comprehensions:

1. Comprehensions are compact ways to create complicated
2. [f(var,…) for var in iterable if p(var,…)]
3. What comprehensions aren’t good for is putting information into a data structure and then mutating/changing it during the execution of the comprehension
4. using a set comprehension: notice {} around the comprehension.
1. x = {c for c in "I’ve got plenty of nothing"}

### 30. Dict Comprehensions:

1. {k(var,…) : v(var,…) for var in iterable if p(var,…)}

### 31 Nested Comprehenshion

1. {c for word in [‘i’, ‘love’, ‘new’, ‘york’] for c in word if c not in ‘aeiou’}
1. 循环内外顺序从左到右

### 32. Comprehension PS

1. .join() function
2. Warning:
1. use the result produced in a later part of the computation
2. typically not mutate anything in the comprehension
3. If the purpose of your computation is to mutate something, don’t use a comprehension
3. Tuple Comprehensions are special
1. what it does is produce a special "generator" object that we can iterate over
3. The result of a tuple comprehension is not a tuple: it is actually a generator.
1. 不能index，也没有len()
2. t = tuple( (i for i in ‘abc’) )这样可以变成tuple

## Nine Important/Useful Functions: split/join, any/all, sum/min/max, zip/enumerate

### 33. The split/join methods

1. str.split-> list object，可能会有”空字符串，如果有两个相邻符号的话
2. str.join(iterable)
1. iterable就行，但是产生的元素必须是Str
2. 只在两两之间加Str,最后一项后面没有

### 34. The all/any functions (and their use with tuple comprehensions)

1. The "all" function takes one iterable argument (and returns a bool value)
1. it returns True if ALL the bool values produced by the iterable are True
2. it can stop examining values and return a False result when the first False is produced
2. The "any" function takes one iterable argument (and returns a bool value):
1. it returns True if ANY the bool values produced by the iterable are True;
2. it can stop examining values and return a True result when the first True is produced (ultimately, if no True is produced it returns False).
3. These functions can be used nicely with tuple comprehensions

### 35. Efficiency

1. all( predicate.is_prime(x) for x in range(2,1000000) ) vs all( [predicate.is_prime(x) for x in range(2,1000000)] )
1. 后者慢，因为他先循环创造一个list，再循环验真值

### 36. The sum/max/min functions (and their use with tuple comprehensions)

1. The simple versions of the sum function takes one iterable argument:
1. 真正的sum, sum(iterable,init_sum=0)
2. The min/max functions require that the iterable produce values that can be compared with each other:
1. calling min([2,’a’,3]) raises a TypeError
2. if the iterable produces no values (e.g., min([]), min and max each raise a ValueError

### 37. Zip:

1. zip that takes an arbitrary number of iterable arguments and zips/interleaves them together
2. What zip actually produces is a generator
3. to "get the result itself" we should use a for loop or constructor (as shown in most of the examples below) to iterate over the generator result of calling zip.
4. zip( ‘abc’, (1, 2) ) => (a,1),(b,2) 没有C
5. So the number of values in the result is the minimum of the number of values of the argument iterables.

### 38. Enumerate

1. It also also produces a generator as a result,
2. but has just one iterable argument, and an optional 2nd argument that is a starting number
3. It produces tuples whose first values are numbers
1. 注意结果元组元素顺序
4. The generator question mostly has to do with space efficiency when iterating over very many values

### 39. **kargs for dictionary of not-matched named arguments in function calls

1. If we use it to specify this kind of parameter, it must occur as the last parameter.
2. kargs stands for keyword arguments
3. they are all put in a dictionary that is stored in the last parameter named kargs.
1. {‘c’: 3, ‘d’: 4}
4. Without **kargs, using the rules specified before, Python would report a TypeError exception (by rule M5(d)),
5. We will use **kargs to understand a special use of of dict constructors
6. Using * and ** followed by the parameter name as ARGUMENTS IN FUNCTION CALLS expands all the values in the tuple/dict respectively to represent arguments
7. Using the parameter names by themselves in the function is equivalent to using the tuple/dict respectively.

### 41. 4.6: Sequence Types includes Lists (mutable) and Tuples (immutable)

1. These sequence operations (operators and functions) are defined in 4.6.1
1. x in s,
2. x not in s,
3. s + t,
4. s * n,
5. s[i],
6. s[i:j],
7. s[i:j:k],
8. len(s),
9. min(s),
10. max(s),
11. s.index(x[, i[, j]]),
12. s.count(x)
2. Mutable sequence allow the following operations, defined in 4.6.3
1. s[i] = x ,
2. s[i:j] = t,
3. del s[i],
4. s[i:j:k] = t,
5. del s[i:j:k],
6. s.append(x)
7. s.clear(), 删掉所有元素
8. s.copy(),
9. s.extend(t),
10. s.insert(i, x),
11. s.pop(),
12. s.pop(i),
13. s.remove(x),
14. s..reverse()

### 42. 4. 9: Set Types includes set (mutable) and frozenset (immutable)

1. These set (operators and functions) are defined in 4.6.1.9
1. isdisjoint(other),
2. issubset(other),
3. set <= other,
4. set < other,
5. issuperset(other),
6. set >= other,
7. set > other,
8. intersection(other, …),
2. Sets, which are mutable, allow the following operations
1. update(other, …),
2. intersection_update(other, …),
3. difference_update(other, …),
4. symmetric_difference_update(other),
5. remove(elem),
7. pop(),
8. also the operators |= (union update), &= (intersection update), -= (difference update), ^= (symmetric difference update)

### 43 4.10 Mapping Types includes dict and defaultdict (both mutable)

1. These dict (operators and functions) are defined in 4.10
1. fromkeys(seq[, value]),
2. get(key[, default]),
3. pop(key[, default]),
4. popitem(),
5. setdefault(key[, default]),
6. update([other]),
7. values()

### 44. Using _ as a variable Name:

1. ks = [k for k,_ in list_of-2-tuples…]
2. for in [1,2,3]: print()

### 45. Exceptions: example from prompt_for_int

1. We do two things with exceptions in Python:
1. we raise them (with the raise statement)
2. and we handle them (with the try/except statement)
2. A function raises an exception if it cannot do the job it is being asked to do.
3. Note that exception handling is very powerful, but should be avoided if a boolean test can easily determine whether a computation will fail

### 46. Name Spaces (for objects): dict

1. Every object has a special variable named dict that stores all its namespace bindings in a dictionary
2. Writing x.a = 1 is similar to writing x.dict[‘a’] = 1;

### Trivial

1. A one value tuple must be written like (1,) with that "funny" comma
2. An empty dict is created by {} and empty set by set()

## [ICS_32A]Lecture2Week4

### Namedtuple

1. namedtuple(‘Name’,["field1","field2",..,"fieldn"]) ->field名要是str
• 大概率不会考：可以用任何一个collection来装这些名字，包括tuple和set，但是set会让顺序变乱
2. 例子 Point
//三个等价的构造
Point(3,5,7)
Point(x=3,y=5,z=7)
Point(z=7,y=5,x=3) //如果明确field名的话，可以调换顺序
3. 参数一定要传的刚刚好，构造新对象的时候不能缺少任何一个参数，也不能多一个函数
4. p1= Point(3,5,7)
p1[0]==p1.x==3
可以用p1[0]调X
可以用p1.x调x
5. 和tuple一样，不可以对fields重新赋值
p1.x=10 =>WRONG

• 几种变相重新赋值的方法：
1. 创建新的对象，并重新赋值
p2=Point(x=p1.x-1,y=p1.y,z=p1.z)
2. _replace 没讲
6. print(p1)
Point(x=3,y=5,z=7)

7. field可以与其他一些东西重名，比如说可以创建p1.input或者p1.print之类的。不会与顶层方法产生冲突。

### TIPS:

1. 编程过程中不要一直编不测试，要模块化编程，然后逐个测试每一个function

## [ICS_32A] Lecture1Week4

### 模块导入 Module Import

#powers.py
def square(n):
return n*n
def cube(n):
return n**3

#program.py
import powers
return int(input())
def run_user_interface():
squared=powers.square(number)
cubed=powers.cube(number)
print(f'The square of {number} is {squared}')
print(f'The cube of {number} is {cubed}')

run_user_interface()
1. Python的模块名不能重，不要把自己的模块命名成math.py之类的
2. Executable module 对比 module that provide tools

# some_else.py

def something():
number=program.ask_for_number() =》出错
3. import x 实质上是让Shell直接把x.py执行一遍，所以全局语句也会被执行
4. 这也就是为什么要用
if name == "main":
5. 更改后的program.py

# program.py

import powers
return int(input())
def run_user_interface():
squared=powers.square(number)
cubed=powers.cube(number)
print(f'The square of {number} is {squared}')
print(f'The cube of {number} is {cubed}')
if __name__ =="__main__":
run_user_interface()

### Network

6. Socket: one end of a network "conversation"
"connecting" a socket means establishing a connection between sockets in two programs.
7. A socket contains two streams:
1. input stream
2. output stream
8. client and server:
1. client is the one that initiates the conversation
2. server is the one that accepts the request and responds to it
9. IP = Internet Protocol
choose你想要连接的machine
10. IP要考
11. IP ： four numbers in the range 0-255, 中间由.分割
256=2^8
12. port端口：0-65535
65536=2^16
13. 一些特殊的IP：127.0.0.1 一般指本机
14. DNS(Domain name service)
maps "fully-qualified domain names"域名 into IP addresses
15. import socket
16. socket.socket是socket里的一种type
17. example_socket=socket.socket()
20. 要创建pseudo files来处理IO streams
input_stream=example_socket.makefile(‘r’)
output_stream=example_socket,makefile(‘w’)

## Exception

try:
the_file= file_path.open("r")
line_count=0
for line in the_file:
line_count += 1
return line_count
except OSError:
print("That file should not be opened")
except ValueError:
print("That file did not contain text")
finally:
if the_file!=None:
the_file.close()
1. finally无论try有无出现问题，都会执行
2. except下只会在try中出现问题时执行
3. except (Exception):
• 如果True，就执行下一行，如果False，就会停止并traceback一个"AssertionError"
• 如果表达式内本来就会出bug，那么就会返回bug信息，而不会有AssertionError
5. nested list of interger有且只有int和nested list of interger

## 【ICS_32A】Lecture1Week3

### 文件File

1. open(path,mode)
2. type(open(path,mode))=>class ‘_io.TextIOwrapper
3. open.mode=mode
4. opne.write(str)，会返回buffer里所有字符串的长度
5. open.close()
6. write之后并不会直接写入文件，而是先存在buffer中，然后在close之前将buffer写入文件中。
7. 与print不同，write没有ending，如果要换行，必须要/n。
8. Path(path)
9. Path.is_file()
10. Path.is_dir()
11. Path.open(mode) => open(path,mode)
12. Path.iterdir()，迭代器，C列表
13. list(Path.iterdir())
14. for i in Path.iterdir()
15. Path.name =>文件名，不带扩展名
16. Path.suffix =>扩展名

### 模块module

1. import math || math.sqrt(9)
2. from math import sqrt || sqrt(9)
3. from math import * || 会导致大量重名

1. 查标准库

## 列表List

1. append
2. extend
3. +=
4. list(xx)
list(range(10))
list(1,2,3)
list("Boo")
5. 剪切slice:
x[1:3]
list[start:end+1:step=1]
x[4:-2]
x[-5:8
x[-5:-1]
x[:-5]
x[4:]
x[len(x)+1:]

## Type Annotation

def len_at_least(s:str,min_length:int) -> bool:
return len(s)>=min_length
• 但是这并不是强制的，你仍然可以传(1,"xx")进去，当然会出错
• 元组tuple： (int,str)
• 列表List: List[int]
• When all else fails, you can use a string litera
• #### None

• 所有方法都会返回一个值，只不过没写的都是返回None
• type(None) => Nonetype

## File

1. file.seek(0)，回到第一行

## Tips:

1. Even though Python does not check types until run-time, THAT DOES NOT mean you shouldn’t think about them until run time. That also doesn’t mean you shouldn’t still want to say something about them in your program.

## 方法 function

1. 方法参数不能多给也不能少给，因为这两种情况都会出错
givemefive() takes xx positional arguments but xxx was given
2. 调用方法出错的Traceback顺序：
1. 什么地方调用了该出错的方法
2. 该出错的方法在哪里出错
3. 出了什么错
3. 局部变量和全局变量 Scope={local variables, global variables}
4. 不要随便用全局变量
5. 你可以在方法中写方法
return int(input("Enter a number, or 0 to stop"))
total=0
while TRUE:
total+=number
6. 调用方法时，会优先找同一层级的方法。也就是说，如果A方法中有local方法B，但是同时也存在和A同级的方法B，那么在A中调用方法B时，会优先调用local方法B。

## 模块 module

7. _name_=_main_
8. 可以在module里写全局语句，他们将在module开始的时候就执行
9. 如果模块本身有全局变量，且在部分方法中使用了该全局变量，那么这些方法将在引用该模块时出错。
10. 方法中方法也是同理

## 其他

1. 从project1开始在方法开头写docstring，来抽象的介绍方法
"""
Takes an argument of any numeric type and returns its square,.
"""
2. 课后可以用这个笔记和32a网上的笔记进行比较，查漏补缺
3. 不能用type(1,2)，只能x=1,2 => type(x)
4. x,y,z="Boo" => x="B",y="o",z="o"

## 条件与循环

### if 语句

if value > 0:
print("Positive")
elif value<0:
print("Negative")
else:
print("Zero")

python使用空格作为语句成分间隔符

### 循环

#### while

    while num<10:
print(num)
num+=1 ##没有++
else:
print("xxx")

### 格式化字符串

    print(f"Hello, (name)")

### range函数

    range(6)==range(0,6,1)
range(1,2**1024)
r = range(10)
r[0]==0
r[1]==1
r[-1]==9
r[-10] WRONG

## 方法

### Python自带方法

1. print
2. 方法本身就是一个对象，其type为function，名字为方法名
type(getsize())
<function getsize at ........>