speaker: Amber(吳思嬋)
# Number
12 # integer
12.5 # float-point
-12.5 # negative
# String
'Hello Word'
# list
[1, 2, 3, 4]
# variable a, object
a = 3
a = 'Hello World'
Variables are created when assigned, can reference any type of object, and must be assigned before they are referenced.
a = 3 # Assign a name to an object
# 1. Create an object to represent the value 3.
# 2. Create the variable a, if it does not yet exist.
# 3. Link the variable a to the new object 3.
a = 3 # It's an integer
a = 'spam' # Now it's a string
a = 1.23 # Now it's a floating point
Whenever a name is assigned to a new object, the space held by the prior object is reclaimed if it is not referenced by any other name or object.
a = 3 # It's an integer
a = 'spam' # Now it's a string
x = 42
x = 'shrubbery' # Reclaim 42 now (unless referenced elsewhere)
x = 3.1415 # Reclaim 'shrubbery' now
x = [1, 2, 3] # Reclaim 3.1415 now
經過這三個statements, print(a)的結果為何?
# exercise1
a = "Hello"
b = a
b = "World"
print(a)
# answer
a = "Hello"
b = a
b = "World"
print(a)
Hello
經過這三個statements, print(a)的結果為何?
# exercise
a = ["Hello"]
b = a
b[0] = "World"
print(a)
# answer
a = ["Hello"]
b = a
b[0] = "World"
print(a)
['World']
# example1
def f():
# function body
print("Hello World")
f() # function call
Hello World
# example2
def f(n):
# function body
print(n)
x = "Hello World"
f(x) # function call
Hello World
# example 3
def g(n):
# function body
tmp = 1
for i in range(1, n+1 ,1):
tmp = tmp * i
return tmp
x = g(5) # function call, 5*4*3*2*1
print(x)
120
# example 4
# Computes the total cost, including 3% sales tax
# on number items at a cost of price each
def total_cost(number, price):
# function body
tax_rate = 0.03 # 3% sales tax
cost = number * price
total = cost + (cost*tax_rate)
return total
n = 5
p = 30
bill = total_cost(n, p)
print('Bill: ',bill)
Bill: 154.5
如果撰寫程式時,將 return object 的 object 省略,在呼叫 function 的階段會發生什麼事?
# return statement without object
def f():
x = 5
return
y = f() # function call
print(y)
# answer
def f():
x = 5
return
y = f() # function call
print(y)
None
# without return statement
def f():
x=5
y = f()
print(y)
None
# 公式:體重(公斤) / 身高^2(公尺^2)
# 過輕:BMI < 18.5; 正常:18.5≦ BMI<24; 過重:24≦BMI
def bmi(height, weight):
calculate = weight / (height*height)
if calculate < 18.5:
result = '過輕'
return result
elif 18.5 < calculate and calculate < 24:
result = '正常'
return result
else:
result='過重'
return result
h = 1.63 #公尺
w = 50 #公斤
r = bmi(h, w)
print("result1: ", r) # 正常
h = 1.80 #公尺
w = 88 #公斤
r = bmi(h, w)
print("result2: ", r) # 過重
result1: 正常 result2: 過重
height = 1.63 #公尺
weight = 50 #公斤
calculate = weight / (height*height)
if calculate < 18.5:
result = '過輕'
elif 18.5 < calculate and calculate < 24:
result = '正常'
else:
result='過重'
print("result1: ", result)
height = 1.80 #公尺
weight = 88 #公斤
calculate = weight / (height*height)
if calculate < 18.5:
result = '過輕'
elif 18.5 < calculate and calculate < 24:
result = '正常'
else:
result='過重'
print("result2: ", result)
result1: 正常 result2: 過重
# Procedural decopsition example
# pizza-making robot
def mixing_the_dough() #和麵
def rolling_it_out() #桿麵
def adding_toppings() #放料
def baking_it() #烤
import math
x = math.sqrt(4)
print(x)
y = math.sqrt(2)
print(y)
定義一個function f,可以將 a, b 的值互換後,需回傳值回來。
定義一個function f, 判斷a, b 大小關係, 回傳字串結果, a>b, a=b 或 a<b
x = 99 # Global (module) scope x
def f():
x = 88 # Local (function) scope x: a different variable
當我們使用variable, python 在scope中搜尋variable的順序為 L, E, G 最後是 B
# Global scope
x = 99 # X and f assigned in module: global
def f(y): # Y and Z assigned in function: locals
# Local scope
z = x + y # X is a global
return z
f(1) # function1 in module: result=100
100
import builtins
dir(builtins)
['ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException', 'BlockingIOError', 'BrokenPipeError', 'BufferError', 'BytesWarning', 'ChildProcessError', 'ConnectionAbortedError', 'ConnectionError', 'ConnectionRefusedError', 'ConnectionResetError', 'DeprecationWarning', 'EOFError', 'Ellipsis', 'EnvironmentError', 'Exception', 'False', 'FileExistsError', 'FileNotFoundError', 'FloatingPointError', 'FutureWarning', 'GeneratorExit', 'IOError', 'ImportError', 'ImportWarning', 'IndentationError', 'IndexError', 'InterruptedError', 'IsADirectoryError', 'KeyError', 'KeyboardInterrupt', 'LookupError', 'MemoryError', 'ModuleNotFoundError', 'NameError', 'None', 'NotADirectoryError', 'NotImplemented', 'NotImplementedError', 'OSError', 'OverflowError', 'PendingDeprecationWarning', 'PermissionError', 'ProcessLookupError', 'RecursionError', 'ReferenceError', 'ResourceWarning', 'RuntimeError', 'RuntimeWarning', 'StopAsyncIteration', 'StopIteration', 'SyntaxError', 'SyntaxWarning', 'SystemError', 'SystemExit', 'TabError', 'TimeoutError', 'True', 'TypeError', 'UnboundLocalError', 'UnicodeDecodeError', 'UnicodeEncodeError', 'UnicodeError', 'UnicodeTranslateError', 'UnicodeWarning', 'UserWarning', 'ValueError', 'Warning', 'ZeroDivisionError', '__IPYTHON__', '__build_class__', '__debug__', '__doc__', '__import__', '__loader__', '__name__', '__package__', '__spec__', 'abs', 'all', 'any', 'ascii', 'bin', 'bool', 'bytearray', 'bytes', 'callable', 'chr', 'classmethod', 'compile', 'complex', 'copyright', 'credits', 'delattr', 'dict', 'dir', 'display', 'divmod', 'enumerate', 'eval', 'exec', 'filter', 'float', 'format', 'frozenset', 'get_ipython', 'getattr', 'globals', 'hasattr', 'hash', 'help', 'hex', 'id', 'input', 'int', 'isinstance', 'issubclass', 'iter', 'len', 'license', 'list', 'locals', 'map', 'max', 'memoryview', 'min', 'next', 'object', 'oct', 'open', 'ord', 'pow', 'print', 'property', 'range', 'repr', 'reversed', 'round', 'set', 'setattr', 'slice', 'sorted', 'staticmethod', 'str', 'sum', 'super', 'tuple', 'type', 'vars', 'zip']
# Global scope
w = 21 # W and outer assigned in module: global
def outer(x):# X and inner assigned in enclosing function: Enclosing def locals
def inner(y): # Z, Y assigned in function: local
z = w + x + y # W is a global (21+88+1)
print(z)
inner(1)
outer(88)
110
# exercise1
x = 'Spam'
def func():
print(x)
func()
# answer
x = 'Spam'
def func():
print(x)
func()
Spam
# exercise2
x = 'Spam'
def func():
x = 'HI!'
func()
print(x)
# answer
x = 'Spam'
def func():
x = 'HI!'
func()
print(x)
Spam
# exercise3
x = 'World'
def func():
x = 'Hello'
print(x)
func()
print(x)
# answer
x = 'World'
def func():
x = 'Hello'
print(x)
func()
print(x)
Hello World
# exercise 4
w = 22
def outer():
w = 23
def inner():
w = 24
print('first: ', w) # first print
inner()
print('second: ', w) # second print
outer()
print('third: ', w) # third print
# answer
w = 22
def outer():
w = 23
def inner():
w = 24
print('first: ', w) # first print
inner()
print('second: ', w) # second print
outer()
print('third: ', w) # third print
first: 24 second: 23 third: 22
# example
x = 88 # Global x
def f():
global x
x = 99 # Global x: outside def
f()
print(x)
99
The function object remembers values in enclosing scopes regardless of whether those scopes are still present in memory.
# This defines an outer function that simply generates and returns a nested function without calling it.
# maker makes action, but returns action without running it.
def maker(n):
def action(x): # Generate and return action
return x * n # action retains N from enclosing scope return action
return action
f = maker(2) # Pass 2 to argument N
print(f)
print(f(3)) # Pass 3 to X, N remembers 2: 3*2=6
print(f(4)) # Pass 4 to X, N remembers 2: 4*2=8
<function maker.<locals>.action at 0x1040afae8> 6 8
def maker(n):
def action(x): # Generate and return action
return x * n # action retains N from enclosing scope return action
return action
f = maker(2) # Pass 2 to argument N
g = maker(3) # Pass 3 to argument N
print(f)
print(f(4)) # Pass 4 to X, N remembers 2: 2*4=4
print(g)
print(g(4)) # Pass 4 to X, N remembers 3: 3*4=6
<function maker.<locals>.action at 0x1040afa60> 8 <function maker.<locals>.action at 0x1040afae8> 12
# advanced technique
# lambda arg1, arg2, ....: expression
def maker(n):
return lambda x: x * n
h = maker(3)
print(h(4))
請試著用 Factory Function 的方法, 計算 N 的 X 次方。
請試著用 Factory Function 的方法, 計算交通使用 公車, 汽車, 機車 的碳足跡排放量。
碳足跡計算方式
example
Everything in python is an object
a = 3
print(id(a), id(3))
4394978016 4394978016
def f(a): # a is assigned to (references) the passed object
a = 99 # Changes local variable a only
b = 88
f(b) # a and b both reference same 88 initially
print(b) # b is not changed
88
def changer(b): # Arguments assigned references to objects
print('before_b:',b)
b[0] = 'spam' # Changes shared object in place
print('after_b:',b)
print('b_id:',id(b))
test_list = [1, 2]
changer(test_list) # Pass mutable object
print('L:', test_list) # l is different
print('L_id:', id(test_list))
before_b: [1, 2] after_b: ['spam', 2] b_id: 4434998728 L: ['spam', 2] L_id: 4434998728
Avoiding Mutable Argument Changes: If we don’t want in-place changes within functions to impact objects we pass to them, though, we can simply make explicit copies of mutable objects,
def changer(b): # Arguments assigned references to objects
b[0] = 'spam' # Changes shared object in place
test_list = [1, 2]
copy_list=test_list[:]
print('before: L:', test_list, '; L_id:', id(test_list))
print('before: copyL:', copy_list, '; copyL_id:', id(copy_list))
changer(copy_list)
print('after: L:', test_list, '; L_id:', id(test_list))
print('after: copyL:', copy_list, '; copyL_id:', id(copy_list))
before: L: [1, 2] ; L_id: 4433557320 before: copyL: [1, 2] ; copyL_id: 4435469832 after: L: [1, 2] ; L_id: 4433557320 after: copyL: ['spam', 2] ; copyL_id: 4435469832
Arguments are passed by automatically assigning objects to local variable names
Assigning to argument names inside a function does not affect the caller
Changing a mutable object argument in a function may impact the caller.
# positionals example
def f(x, y, z):
print(x, y, z)
f(1, 2, 3)
1 2 3
# keywords example
def f(x, y, z):
print(x, y, z)
f(z=4, y=5, x=6)
6 5 4
# defaults and postional
def f(x, y, z=3):
print(x, y, z)
f(4, 5)
f(4, 5, 6)
4 5 3 4 5 6
# varargs collecting, one * for tuple
def f1(*args):
print(args)
f1(1, 2, 3, 4, 5, 6, 8, 'hello')
f1('how', 'do', 'you', 'do')
def f2(x, y, *args):
print(x,y)
print(args)
f2(1,2,3,4,5,6,8,'hello')
(1, 2, 3, 4, 5, 6, 8, 'hello') ('how', 'do', 'you', 'do') 1 2 (3, 4, 5, 6, 8, 'hello')
# varargs collecting, two * for dictionary
def f(**kwargs):
print(kwargs)
f(key1=1, key2=2, key3=3)
{'key1': 1, 'key2': 2, 'key3': 3}
# mix varargs collecting
def mix(x, y, *args, **kwargs):
print(x,y)
print(args)
print(kwargs)
mix(1, 2, 3, 4, 5, 6, 8, 'hello', key1=1, key2=2, key3=3)
1 2 (3, 4, 5, 6, 8, 'hello') {'key1': 1, 'key2': 2, 'key3': 3}
# Varargs unpacking
def f(x, y, z):
print(x, y, z)
args=(1, 2, 3)
f(*args)
kwargs = {'x':1, 'y':2, 'z':3 }
f(**kwargs)
1 2 3 1 2 3
# exercise
# What is the output of the following code?
def f1(a, b=4, c=5):
print(a, b, c)
f1(1, 2)
def f2(a, b, c=5):
print(a, b, c)
f2(1, c=3, b=2)
def f3(a, *args):
print(a, args)
f3(1, 2, 3)
def f4(a, **kargs):
print(a, kargs)
f4(a=1, c=3, b=2)
def f5(a, b, c=3, d=4):
print(a, b, c, d)
f5(1, *(5, 6))
# Function objects example: assigned to name
def f(msg):
print(msg)
f('hello word!')
x = f
x('hello word!')
hello word! hello word!
# Function objects example: pass to other function
def f(msg):
print(msg)
def g(f_obj, arg):
f_obj(arg)
g(f, 'Hello world!') # Pass the function to another function
Hello world!
# Function objects example: embedded in data structures
def f(msg):
print(msg)
test_list = [(f, 'Hello'), (f, 'World!!')]
for (f_obj, arg) in test_list:
f_obj(arg) # Call functions embedded in containers
Hello World!!
# Function objects example: return
def f(msg):
def g(msg2):
print(msg+':'+msg2)
return g
t = f('hello')
t('world!')
hello:world!
# sum for 1+2+3+...+10
def f(n):
print('n:',n) # Trace recursive levels
if n==1:
return 1
else:
return f(n-1)+n
print('answer: ',f(10))
# f(10)= f(9)+10 -> next level
# f(9) = f(8)+9 -> next level
# f(8) = f(7)+8 -> next level
# ...
# f(3)=f(2)+3 -> next level
# f(2)=f(1)+2 -> next level
# f(1) return 1 -> next level
# f(2)=f(1)+ 2 = 1 + 2 -> previous level, f(1) is 1 now
# f(3)=f(2)+ 3 = 3 + 3 -> previous level, f(2) is 3 now
#...
n: 10 n: 9 n: 8 n: 7 n: 6 n: 5 n: 4 n: 3 n: 2 n: 1 answer: 55
仿照上一個例子,請試著寫數字連乘的遞迴函式,計算出f(10)等於多少。
請試著寫數字連乘的遞迴函式,計算出費氏(Fibonacci)數列 F(20),公式如下:
# recursion
def f(n):
if n==1:
return 1
else:
return f(n-1) + n
print('receusion: ', f(10))
# loop
total = 0
for i in range(11): # 0, 1, ,2 ,3 ,4 , ..., 10
total = total + i
print('loop', total)
receusion: 55 loop 55
每次只能移動一個圓盤
大盤不能疊在小盤上面。
可將圓盤臨時置於B杆,也可將從A杆移出的圓盤重新移回A杆,但都必須遵循上述兩條規則。
** Question: 5個圓盤,總共要移動多少次,移動的順序為何? **