CMU-15112课程笔记

这是CMU-15112 Python的课程笔记

很多只是课程笔记的简单摘录,便于回顾

贴一下课程地址吧https://www.kosbie.net/cmu/fall-20/15-112/index.html

Chapter 1 Getting Started

Some Notes

  1. some bulidin constant: math.pi math.e
  2. almost equal
def almostEqual(d1, d2):
    epsilon = 10**-10
    return (abs(d2 - d1) < epsilon)
  1. short_circuit

Variables and Functions

Conditionals

1. 	if():
	else:
2. 	if():
	elif():
	else:
3. 	if-else expression
    return n if (n >= 0) else -n

Chapter 2 Loops

for loops and range

for x in range(m,n+1):
for x in range(n+1):
for x in range(m,n+1,step):	% third parameter is step

while loops

while(n >= 10):
% don't us while loop over a fixed range

break and continue

Chapter 3 Strings

String Literals

1. 'string'		"string"	"""string"""
2. escape sequences		\n \t ...
3. repr() shows a representation of the data contained in the string.

String Operators

1. "abc" + "def" = "adcdef"
2. "ring" in "string" = True
3. s = "abcdefgh"
4. s[7] == s[-1]
5. s[2:5] == "cde"		#slicing string
6. s[1:7:2] == "bdf"  	#slicing with a step parameter
7. Rversing a string
8. def reverseString(s):
9.	   return s[::-1]

Looping over Strings

1.	for i in range(len(s)):
2.	for c in s:
3.	for name in name,split(","):
4.	#	names.split(",") produces a list.
5.	for line in quotes.splitlines():
6.	#	split strings in lines

Strings are Immuteable
You can’t change strings,you must creat a new string
String and Aliases
String-related Built-In Function

1. str()  	len() 	# str() change to string type
2. chr()	ord()	# chr(65) = "A"  ord(A) = 65
3. eval()			# just don't use it

String Methods

1. Character types:
2. isalnum() isalpha() isdigit() islower() isupper() isspace()
3. String edits:
4. s.lower()	s.upper()	
5. s.replace("nice","sweet")	# replace nice with sweet
6. s.strip()		#	remove space in the bnegining and at the end

Substring search

1. s.count("is")		#	2
2. s.startswith("Do")	#	True
3. s.endwith("!")		#	False
4. s.find("and")		# 	return the first char's index
   						#	return -1 if not found
5. s.index("or")		#	will crash if not found

String Formatting

1. %s	string
2. %d	integer
3. %f	float
4. %.[precision]f	%0.2f
5. multiple values
6. :	print("There are %d cats. %s!!!" % ( cats, exclamation))
7. format right-aligned(右对齐) with % [minWidth]
8. :	print("%10s %10s" % ("dogs", "cats"))
9. format left-aligned with %-[minWidth]
10. :	print("%-10s %-10s" % ("dogs", "cats"))

String Formatting with f Strings

print(f'Did you know that {x} + {y} is {x+y}?')

Chapter 4 1d Lists

The Basics

1. Creat Empty List
   :	a = []
 		b = list()
2. List Functions and Operations
   :	len()	min()	max()	sum()

Lists are Mutable

1. lists are mutable
2. Copy vs Alias
3. :	b = a				# alias	
	 	c = copy.copy(a)	# copy
4. Destructively and Non-destructive

Coding with Lists

1. check for list membership: in
   : 	(2 in a)		# True
   : 	(2 not in a)	# False
2. count occurrences in list: list.count(item)
   : 	a.count(1)
3. find index of item: list.index(item) and list.index(item,start)
   : 	a.index(2,1)
   #	this crashes when item is not in list
   #	Solution: use item in list
4. adding elements
   		a.append()	# destructively
5. add a list of items with list += list2 or list.extend(list2)
  		a += [2,3]
  		a.extend([17,19])
6. insert an item at a given index
  		a.insert(2,42)	# at index 2, insert 42
7. removing elements
   		a.remove(5)			# remove first 5
   remove an item at a given index
   		item = a.pop(3)
   		lastItem = a.pop()
8. looping over list
   		for index in range(len(a)):
   		for item in a:
   Hazard:  don't change a list inside a for loop! it crashes!
   			also don't modifying inside a for-each loop
   			do it inside a while loop
9. Sorting and Reversing
	Destructively:
		list.sort()		list.reverse()
	Non-Destructively:
		b = sorted(a)
		for item in reversed(a):

Tuples(Immutable Lists)

Tuples are like lists,expect they are immutable

1. tuples are useful for swapping!
   		(x,y) = (y,x)
2. 		t = (42,)	# use a comma to force the type to be tuple

List Comprehensions

1. a = [i for i in range(10)]
2. a = [(i*100) for i in range(20) if i%5 == 0]	# can add conditionals
3. Converting Between Lists and Strings
   list(s) convert a string to a list of characters
   		a = list("wahoo!")
   s1.split(s2) convert a string to a list of strings delimited by s2
   		a = "How are you doing tody?".split(" ")
   	"".join(a) convert a list of chars/strings to a single string

Chapter 5 2d Lists

Basics

1. creating 2d lists
  		a = [ [0] * cols ] * rows	# Error: creates shallow copy
  					# creates one unique row,the rest are aliases!
  		for row in range(rows):
  			a += [[0]*cols]
  	or:	a = [ ([0] * cols) for row in range(rows)]
  	best option:
  		def make2dList(rows, cols):
    		return [ ([0] * cols) for row in range(rows) ]
2. rows = len(a)
   cols = len(a[0])
3. Copying and Aliasing 2d Lists
   b = copy.copy(a)	# Error: shallow copy
   					# modify a will change b
   b = deepcopy(a)	# correct!
   		a = [[0]*2]*3        # makes 3 shallow copies of the same row
		a = copy.deepcopy(a) # meant to make each row distinct
		a[0][0] = 42
		a = [[42,0],[42,0],[42,0]]
	# deepcopy preserves any already-existing aliases perfectly!
# Advanced: alias-breaking deepcopy	
def myDeepCopy(a):
    if (isinstance(a, list) or isinstance(a, tuple)):
        return [myDeepCopy(element) for element in a]
    else:
        return copy.copy(a)

    a = [[0]*2]*3     # makes 3 shallow copies of the same row
    a = myDeepCopy(a) # once again, meant to make each row distinct
    a[0][0] = 42      # so we hope this only modifies first row
    print(a)          # finally, prints [[42, 0], [0, 0], [0, 0]]
    # now all the aliases are gone!

Printing 2d Lists

a clear way to print list

def maxItemLength(a):
    maxLen = 0
    rows = len(a)
    cols = len(a[0])
    for row in range(rows):
        for col in range(cols):
            maxLen = max(maxLen, len(str(a[row][col])))
    return maxLen
# Because Python prints 2d lists on one row,
# we might want to write our own function
# that prints 2d lists a bit nicer.
def print2dList(a):
    if (a == []):
        # So we don't crash accessing a[0]
        print([])
        return
    rows, cols = len(a), len(a[0])
    fieldWidth = maxItemLength(a)
    print('[')
    for row in range(rows):
        print(' [ ', end='')
        for col in range(cols):
            if (col > 0): print(', ', end='')
            print(str(a[row][col]).rjust(fieldWidth), end='')
        print(' ]')
    print(']')

Nested Looping over 2d Lists

nothing special

Accessing 2d Lists by Row or Column

1. whole row
   		a = [ [1,2,3],[4,5,6] ]
   		rowList = a[row]
2. a whole column
   		colList = []
   		for i in range(len(a)):
   			colList += [a[i][col]]
   		colList = [ a[i][col] for i in range(len(a))]

Non-Rectangular(“Ragged”) 2d Lists

for row in range(rows):
	cols = len(a[row])
	for col in range(cols):

3d Lists

nothing special

Chapter 6 Sets and Dictionaries

Sets

Basics

Creat sets
	s = set()
	s = set(["cat","cow","dog"])
	s = {2,3,5}			# statically-allocated set
caution:
	{} is not an empty set
	s.add(7)
	s.remove(3)		# raise an error if 3 is not in s

Properties of Sets

1. Sets are Unordered
2. Elements are Unique
3. Elements Must Be Immutable
4. Sets are very Efficient # constant time for common operations
5. Sets work based on Hashing
	python provide *hash* function
	it takes any value as input and returns an integer

Dictionaries(Similar to Map in C++)

Basics

Dictionaries map keys to values,but keys can be any immutable value!
Creating Dictionaries
	d = dict() or d = {}
	pairs = [("cow",5),("dog",98),("cat",1)]
	# Statically-allocate a dictionaies 
	d = {"cow":5, "dog":98, "cat":1}	
	d["e"] = "wow"	# add or update
	del d["e"]		# crash if the key is not in d
	d.get("z",42)	# find the value of the key if it's in the dict
					# or return the second(default) value if it's not

Properties of Dictionaries

1. Keys are unordered
2. Keys are unique
3. Keys must be immutable
4. Values are Unrestricted	# values can be mutable(may be a list)
#	eg:	d = dict()
		a = [1,2]
		d["fred"] = a	# d: "fred":[1,2]
        a += 3			# d: "fred":[1,2,3]
5. Dictionaries are very Efiicient	# cause keys are stored as a set

Chapter 7 Recursion

def recursiveFunction():
	if(base case):
		do something non-recursive
	else:		#	recursive case
		do something recursive

Multiple Base/Recursive Cases

def power(base,expt):
	if(expt==0):
		return 1
	elif(expt<0):
		return 1.0/power(base,abs(expt))
	else:
		return base*power(base,expt-1)

Details(i guess…)

1.Infinite Recursion and Stack Overflow(please don’t do that)
2.Recursive Debugging

    def rangeSum(lo, hi, depth=0):
        print("   " * depth + "rangeSum(" + str(lo) + ", " + str(hi) + ")")			# 利用depth来显示递归的层数
        if depth == 10:
            input("Pause (press enter to continue)")
        if (lo > hi):
            result = 0
        else:
            result = lo + rangeSum(lo + 1, hi, depth + 1)
        print("   " * depth + "-->", result)
        return result

3.Warpper Function(not interested)
当不能改变函数参数时,可以使用warpper function,在不改变函数参数的同时使用加了函数参数的函数(不如写default parameter,见4)

def rangeSum(lo, hi):	# Wrapper Function
    return rangeSumHelper(lo, hi, 0)

def rangeSumHelper(lo, hi, sumSoFar):
    if (lo > hi):
        return sumSoFar
    else:
        return rangeSumHelper(lo+1, hi, lo+sumSoFar)

4.Default Parameters
(1)default parameters

def rangeSum(lo, hi, sumSoFar=0):
    if (lo > hi):
        return sumSoFar
    else:
        return rangeSum(lo+1, hi, lo+sumSoFar)

(2)do not use mutable default values(in recursion or elsewhere)
python only creat default values once ever and reuse those values on each call
所以如果使用了可变的default values,在第二次以后的调用基本没法得到正确的结果
Warning: This is BROKEN because it uses a mutable default value

def reverseList(L, reversedSoFar=[]):
    if (L == [ ]):
        return reversedSoFar
    else:
        reversedSoFar.insert(0, L[0])
        return reverseList(L[1:], reversedSoFar)
print(reverseList([2,3,4])) # [4, 3, 2] (it works the first time!)
print(reverseList([5,6,7])) # [7, 6, 5, 4, 3, 2] <-- OH NO!!!

第一次调用后,reversedSoFar = [4,3,2] 而不是空list
(3)Workarounds instead of mutable default values
1)Do not mutable the default value
do it nondestructive!
2)Use None as default value cause None is not mutable # niccccccccce

#Fix  use None instead of [] and create a new list to start
def reverseList(L, reversedSoFar=None):
    if (reversedSoFar == None):
        reversedSoFar = [ ] # this creates a new list each time!
    if (L == [ ]):
        return reversedSoFar
    else:
        reversedSoFar.insert(0, L[0])
        return reverseList(L[1:], reversedSoFar)

3)Use a wrapper function # wrapper function? 狗都不用 dog.jpg
4)Use a different approach without default value # Nonsense
5.a method(i guess…)
Divide and Conquer 分而治之
6.Combining Iteration and Recursion
i don’t know,just paste an example

# Problem: given a list a, return a list with all the possible subsets of a.		给定一个list,返回其所有可能的子集
def powerset(a):
    # Base case:
    if (len(a) == 0):
        return [ [] ]
    else:
        # Recursive Case: remove the first element, then find all subsets of the remaining list. Then for each subset, use two versions of that subset:one without the first element, and another one with it.
        partialSubsets = powerset(a[1:])
        allSubsets = [ ]
        for subset in partialSubsets:	# iteration
            allSubsets.append(subset)
            allSubsets.append([a[0]] + subset)	# recursion
        return allSubsets

Chapter 8 OOP

Part 1 Using Objects and Methods

Methods vs Functions

methods: s.f() function f(s)

s = 'This could be anything!'
print(len(s))		# len is a function
print(s.upper())	# upper is a string method

Classes and Instances

Classes are also called “Types” in python
Instances are values of a given class or type # class 的实例

OOP(Object-Orinted Programming)

Every value/instance/class in Python is an object

Mutable Objects with Dataclass Classes

we can use make_class to creat classes then to creat mutable objects

from dataclasses import make_dataclass

# Now we can create a new class named Dog where instances (individual dogs) have 3 properties (fields): name, age, and breed

Dog = make_dataclass('Dog', ['name', 'age', 'breed'])
dog1 = Dog(name='Dino', age=10, breed='shepherd')
print(dog1)        # prints: Dog(name='Dino', age=10, breed='shepherd')

Part 2 Writing Classes and Methods

Constructors 构造函数

class Dog(object):
# constructor name must be _init_
# instances name must be self
    def __init__(self, name, age):
        # pre-load the dog instance with the given name and age:
        self.name = name
        self.age = age

Writing Methods

start with a function

class Dog(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age
# Here is a function we will turn into a method:
def sayHi(dog):
    print(f'Hi, my name is {dog.name} and I am {dog.age} years old!')

Turn the function into a method, and the function call into a method call

class Dog(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age
    # Now it is a method (simply by indenting it inside the class!)
    def sayHi(self):	#	Attention  缩进不同,这个sayHi在Dog类中
        print(f'Hi, my name is {self.name} and I am {self.age} years old!')

Methods can take additional parameters;
Methods can also set properties;

class Dog(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age
        self.woofCount = 0   #在构造函数中初始化properties

    def bark(self, times):
        # Then we can set and get the property in this method
        self.woofCount += times
        print(f'{self.name} says: {"woof!" * times} ({self.woofCount} woofs!)')

Advantages of Classes and Methods

Encapsulation 封装
Organizes code 一个类包括该类的数据和方法。
Promotes intuitive design
Restricts access 限制访问
upper is a method on strings but not booleans, so we cannot even call True.upper()

** Polymorphism 多态性**
Polymorphism: the same method name can run different code based on type, like so:
相同的方法名可以根据类运行不同的代码

class Dog(object):
    def speak(self):
        print('woof!')

class Cat(object):
    def speak(self):
        print('meow!')

for animal in [ Dog(), Cat() ]:
    animal.speak() # same method name, but one woofs and one meows!

Part 3 Special Methods + Inheritance + More

Type Testing

type(a) isinstance(a,A)

Methods

1.Equality Testing(eq)
Shouldn’t a1 == a2? 两个instacne相等 你怎么说(Teacher Ma’s voice

class A(object):
    def __init__(self, x):
        self.x = x
    def __eq__(self, other):	# __eq__  double _
# __eq__ method tell python how to evalute  the equality of two objects.
        return (isinstance(other, A) and (self.x == other.x))
        # it don't crash on unexpected types of other
a1 = A(5)	
a2 = A(5)
print(a1 == a2)  # True
print(a1 == 99)  # False (huzzah!)

2.Converting to Strings (_str and repr)

class A(object):
    def __init__(self, x):
        self.x = x
#The __str__ method tells Python how to convert the object to a string, #但有些情况下不行 比如 print([a])
    def __str__(self):
        return f'A(x={self.x})'

better solution

# Note: repr should be a computer-readable form so that
# (eval(repr(obj)) == obj), but we are not using it that way.
# So this is a simplified use of repr.
# 只用一个repr可以不用str了 
# The __repr__ method is used inside lists (and other places):
class A(object):
    def __init__(self, x):
        self.x = x
    def __repr__(self):
        return f'A(x={self.x})'
a = A(5)
print(a) # prints A(x=5) (better)
print([a]) # [A(x=5)]		两种方法都可print object
  1. Class-Level Features
  1. Class Attributes
    Class Attributes are values specified in a class that are shared by all instances of that class! We can access class attributes from any instance of that class, but changing those values anywhere changes them for every instance.
class A(object):
    dirs = ["up", "down", "left", "right"]	# class sttributes

# typically access class attributes directly via the class
print(A.dirs) # ['up', 'down', 'left', 'right']
# can also access via an instance:
a = A()
print(a.dirs)

# but there is only one shared value across all instances:
# 所有class 共享一个value 只有一份copy 从任意instance中改变value
# 会导致所有class的value都会改变
a1 = A()
a1.dirs.pop() # not a good idea
a2 = A()
print(a2.dirs) # ['up', 'down', 'left'] ('right' is gone from A.dirs)

2) Static Methods
Static Methods in a class can be called directly without necessarily making and/or referencing a specific object.
其实就是一个跟该类有关的funtion,你又不想把它作为method
为了避免namespace 命名空间不被污染(因为这个function只和你这个类有关)
就把它放入类中

class A(object):
    @staticmethod
    def f(x):
        return 10*x
class B(object):
	@staticmethod
	def f(x):
		return 1000000*x
print(A.f(42)) # 420 (called A.f without creating an instance of A)
print(B.f(42)) # 42000000 都是f 但是是不同的函数

4. Inheritance

  1. Superclass
class A(object):	# Superclass
    def __init__(self, x):
        self.x = x
    def f(self):
        return 10*self.x

class B(A):			# Subclass
    def g(self):
        return 1000*self.x

2 Overriding methods
We can change a method’s behavior in a subclass by overriding it.

class A(object):
    def __init__(self, x):
        self.x = x
    def f(self):
        return 10*self.x
    def g(self):
        return 100*self.x

class B(A):
    def __init__(self, x=42, y=99):	# overide __init__ in A
        super().__init__(x) # call overridden init!	
        self.y = y			## super().将其视为其上一级的父类
    #   前面是基类(父类)都会做的  后面是子类特殊的部分
    def f(self):
        return 1000*self.x
    def g(self):
        return (super().g(), self.y)

3) isinstance vs type in inherited classes

class A(object): pass
class B(A): pass
a = A()
b = B()
# type(a) 返回该object精确的类
# isinstane(a,A) 返回a是否属于class A 即使a是A的子类 也返回True
print(type(a) == A) # True
print(type(b) == A) # False
print(isinstance(a, A)) # True
print(isinstance(b, A)) # True (surprised?)

Part 4 The hash method

(Objects) Using in Sets and Dictionaries (hash and eq)
The problem:Objects do not seem to hash right by default:
object是无法hash的
**The solution: hash and eq
The hash method tells Python how to hash the object.
你所选择hash的属性应当是immutable的类型,并且应当永远不变
**

# 你的getHashables方法应当返回你的hash所要求的值
# 也就是你的__eq__中所需要的用来测试相等的值
# 一个适当的hash应当只测试不变的值

class A(object):
    def __init__(self, x, y):
        self.x = x
        self.y = y
    def getHashables(self):
        return (self.x,self.y) # return a tuple of hashables
    def __hash__(self):
        return hash(self.getHashables())
    def __eq__(self, other):
        return (isinstance(other, A) and 
        		(self.x == other.x)) and
        		(self.y == y))

s = set()
s.add(A(5))
print(A(5) in s) # True (still works!)

d = dict()
d[A(5)] = 42
print(d[A(5)]) # works!

Chapter 9 Monte Carlo Methods

Monte Carlo Methods NP-Completeness and The Halting Problem
** i just skip this part**

Chapter 10 Exceptions and Functions Redux

Exceptions

Basic Exception Handling(try/except)

print("This is a demonstration of the basics of try/except.")
try:	#  try 一些可能出现exception的代码
    print("Here we are just before the error!")
    print("1/0 equals:", (1/0))
    print("This line will never run!")
except:	#   一旦出现exception 马上跳转执行下面的语句
    print("*** We just caught an error. ***")
print("And that concludes our demonstration.")	# 假装无事发生

Raising an Exception

自己设计 raise an exception

def lastChar(s):	
    if (len(s) == 0):
        # This is (a simple form of) how you raise your own custom exception:
        raise Exception('String must be non-empty!')
    else: return s[-1]

print(lastChar('abc'))
print(lastChar(''))
print("This line will never run!")

Functions Redux (函数终极版)

Variable length args (*args) 变长参数

def longestWord(*args):
    if (len(args) == 0): return None
    result = args[0]
    for word in args:
        if (len(word) > len(result)):
            result = word
    return result

*(args)会把传入的参数全部接受并且变成一个tuple

Default args

1.example
def f(x,y=10):return (x,y)
2.Do not use mutable default args
def f(x,L=[]):
	L.append(x)
	return L
print(f(1))	# [1]
print(f(2)) # [1,2]	因为上一句调用后L=[1],达不到默认L是empty list
			# 和之前的道理一样
3.One workaround
def f(x,L=None):
	if(L==None):
		L=[]
	L.append(x)
	return L
	# 和之前一样,这样就可以达到每次调用L都初始化为empty list

Function as parameters 函数也可以作为参数传递给函数

def derivate(f,x)::
	h = 10**-8
	return (f(x+h) - f(x))/h
	
def f(x):return 4*x + 3

lambda function

如果不给lambda function分配变量名 那么它只能使用一次

print(derivative(lambda x:3*x**5 + 2,2))
myF = lambda x: 10*x + 42	# 分配后 myF就是一个function了
print(myF(5)) # 92
print(derivative(myF, 5)) # about 10

Keyword args(**kwargs)

def f(x=1, y=2): return (x,y)	# 两个default parameter
print(f()) # (1, 2)
print(f(3)) # (3, 2)
print(f(y=3)) # (1, 3) [here is where we use a keyword arg]

def f(x, **kwargs): return (x, kwargs)
# 加了这个 **kwargs 这个参数就是一个{},(dictionary),默认为空
print(f(1)) # (1, { })
print(f(2, y=3, z=4)) # (2, {'z': 4, 'y': 3})

Functions inside functions

函数f内部定义的函数squared,只可在该函数f内部使用

def f(L):
    def squared(x): return x**2
    return [squared(x) for x in L]
print(f(range(5)))
try:
    print(squared(5))
except:
    print("squared is not defined outside f")

Closures + Non-local variables

squared can access myMap even it’s not in squared
so it’s called non-local variables非局部变量(不是很懂想说什么

def f(L):
    myMap = dict()
    def squared(x):
        result = x**2
        myMap[x] = result
        return result
    squaredList = [squared(x) for x in L]
    return myMap
print(f(range(5)))

Non-local variables fail on setting (use nonlocal)

好像就是通过使用nonlocal关键字来使这函数内部可以使用相同的变量名来访问定义在该函数外的变量,也就是非本地变量non-local variables

def brokenF(L):
    lastX = 0
    def squared(x):
        result = x**2
        lastX = x		# 这样lateX是局部变量,和函数外的lateX不是同一个东西
        return result
    squaredList = [squared(x) for x in L]
    return lastX
print(brokenF(range(5)))	# 0

def fixedF(L):
    lastX = 0
    def squared(x):
        nonlocal lastX	# 这样lateX指的就是外面的lateX了
        result = x**2
        lastX = x
        return result
    squaredList = [squared(x) for x in L]
    return lastX
print(fixedF(range(5)))

Functions that return functions

返回函数的函数,实际上就是根据传入函数的不同会返回不同的函数,见例

def derivativeFn(f):	
    def g(x):
        h = 10**-5
        return (f(x+h) - f(x))/h
    return g	# 根据f 最终返回g,也就是f的导数

def f(x): return 5*x**3 + 10	# f(x)=5x^3+10
fprime1 = derivativeFn(f)		# f'(x)=15x^2
fprime2 = derivativeFn(fprime1)	# f''(x)=30x
print(f(3))    # 145, 5*x**3 + 10 evaluated at x == 3
print(fprime1(3)) # about 135, 15*x**2 evaluated at x == 3
print(fprime2(3)) # about 90, 30*x evaluated at x == 3

Function decorators

**前提是 decorator function必须是返回函数的函数,如上面的例子derivativeFn
然后,这个decorator function中定义的函数(比如说g() ) 必须要有和该函数 h 同样个数的参数
**

def derivativeFn(f):
    def g(x):	# g(x) takes one parameter
        h = 10**-5
        return (f(x+h) - f(x))/h
    return g

@derivativeFn
def h(x): return 5*x**3 + 10	# h(x) also takes one parameter
print(h(3)) # 135, matches fprime1 from above.

# 这样在h(x)上加上@derivativeFn 将其作为h(x)的decorator function
# 之后只要调用h(x) 其实都是将h(X)传入其decorator function
# 它的decorator function返回什么,就是h(x) 返回什么

The End

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值