Introduction to Python

楊皓丞

Python是什麼

  • https://bit.ly/2QQUijK
  • 就像C/C++一樣,是一種程式語言
  • 那我會C/C++了,還要學python幹嘛?

為什麼要學python

  • 易上手,泛用,且必備
  • 易上手:語法較C/C++直觀,適合新手學習
  • 泛用:可以使用許多套件,使python在很多用途中都是最適合的程式語言,這也是他最大的優勢
  • 必備:系上蠻多課程會當作你會寫python,但沒有一門課會真正的花時間教你如何寫python
    • 也可以在2019資訊營當challenge的python TA
      • 這有什麼好處呢
        • 參加就知道了!

今天的課程

  • 由於大家並非寫程式的新手,所以這門課的重點不是從零到有的教大家用python寫程式,而是C與python的差別,也就是語法上的不同
  • 不過講義上的內容編排則是適合沒學過任何程式也能看懂的純python教學

C與python的差異

直譯語言 vs 編譯語言

編譯語言 直譯語言
編譯器將程式碼編譯(compile)成機器碼,產生一個執行檔 直譯器一行一行將程式碼直譯(interpret)成機器碼並執行
只要程式碼中有語法錯誤就無法編譯成功,完全無法執行
因此較難debug
出現語法錯誤那行之前的code都會正常執行,直到遇到錯誤
因此較易debug
執行效率較高 執行效率較低
C/C++ python

如何執行python程式

  • 寫好一個.py的檔案,然後在命令列中使用
    python filename.py
  • 若只是要測試功能,也可以直接在命令列中使用
    python,然後就可以一行一行輸入
  • 如果電腦是windows怎麼辦?
    • 使用Anaconda Prompt
    • 或是更簡單的,連上工作站就好

程式架構上的差異

  • 不需要用一個main function套住主程式
  • 一行指令的最後不用加分號(;)
  • 段落並非用大括號來表示,而是用冒號(:)和縮排
  • 剩餘主要就是語法差異了!

python中的變數型態

  • int
  • float
  • list
  • str
  • bool

int/float

a = 3
b = 3.5
c = 5
d = 2

a + b
#output : 8
a - c
#output : -2
a * c
#output : 15
a / c
#output : 0.6
c % d
#output : 1
#整數除法取餘數
c ** a
#output : 125
#指數運算
c // d
#output : 2
#整數除法取商

int/float大部分的使用上都跟C相同,大家有察覺哪些差異呢?

x = 3
x = x + 1
x
#output : 4
x += 1
x
#output : 5
x ++
# Syntax Error: invalid syntax


a, b = 3, 5
a
#output : 3
b
#output : 5
a, b = b, a
a
#output : 5
b
#output : 3

int/float

  • 變數不用宣告型態,因為python中變數會自己調整型態
  • int型態的3 / 5 = 0.6,變成float了,原理同上
  • 所以多了//來代替常用到的整數除法求商
  • 也多了方便的指數運算**,int和float都可以用(所以開根號可以用a ** 0.5)
  • 等於(=)一樣是賦值的意思,也有跟C一樣的+=,*=,...
  • 不過注意python中沒有++,--的用法
  • 支援多變數同時賦值,用逗號隔開變數就好
  • C中執行 a, b = 3, 5會發生什麼事呢?

list

a = ['hello', 1, 3.0]
a[0]
#output : hello
a[-1]
#output : 3.0
a[1] = 2
a
#output : ['hello', 2, 3.0]

b = [1, 2, 3, 4, 5, 6]
b[1:]
#output : [2, 3, 4, 5, 6]
b[:3]
#output : [1, 2, 3]
b[1:5]
#output : [2, 3, 4, 5]
b[1:5:2]
#output : [2, 4]
b[::-1]
#output : [6, 5, 4, 3, 2, 1]
b[?:?:?]
#output : [5, 4, 3, 2]

list是序列,類似C中的陣列,但功能上較為廣泛

請大家觀察list和C中array的不同

a = [1, 2, 3]
b = [4, 5]

a + b
#output : [1, 2, 3, 4, 5]
a * 2
#output : [1, 2, 3, 1, 2, 3]


a = b = 3
a += 1
a
#output : ?
b
#output : ?

a = b = [1, 2]
a += [3]
a
#output : ?
b
#output : ?
a = ['hello', 1, 3.0]
a[0]
#output : hello
a[-1]
#output : 3.0
a[1] = 2
a
#output : ['hello', 2, 3.0]

b = [1, 2, 3, 4, 5, 6]
b[1:]
#output : [2, 3, 4, 5, 6]
b[:3]
#output : [1, 2, 3]
b[1:5]
#output : [2, 3, 4, 5]
b[1:5:2]
#output : [2, 4]
b[::-1]
#output : [6, 5, 4, 3, 2, 1]
b[4:0:-1]
#output : [5, 4, 3, 2]
a = [1, 2, 3]
b = [4, 5]

a + b
#output : [1, 2, 3, 4, 5]
a * 2
#output : [1, 2, 3, 1, 2, 3]


a = b = 3
a += 1
a
#output : 4
b
#output : 3

a = b = [1, 2]
a += [3]
a
#output : [1, 2, 3]
b
#output : [1, 2, 3]

list

  • python的list中可以放不同型態的元素
  • 可以用a[x:y:z]的方式輕鬆存取list中的一段
  • 支援+和*,+就是序列的串接,*就是連加
  • 可以直接用等於(=)賦值,但當使用變數賦值時,要注意傳送的是參照,而非複製出一個新的一樣的序列
  • python中除了int/float/bool,其餘變數型態大多傳送的都是參照

str(字串)

a = "hello"
b = "world"

a + b
#output : hello world

a * 3
#output : hellohellohello

a[1]
#output : e

c = a + ' ' + b + '!'
c
#output : hello world!
c[0] = 'H'
#output : TypeError: 'str' object does not support item assignment

字串的使用上都也跟C差不多,也跟list很像,不過有個顯著的差異!

str

  • python中的字串是不可修改的(immutable),詳細的意思是不能把其中的元素(字元)指派成其他元素(字元)
  • 這點跟list不一樣,list是可以修改其中的元素的
  • 有一種幾乎跟list相同但不能修改元素的型態,稱為tuple
  • 那如果我想要得到由c字串修改一個字元後得到的新字串怎麼辦?
  • ans: c = 'H' + c[1:]

printf vs print

#include<stdio.h>
int main(){
    printf("資工系桌招募新生中,女生不用繳隊費喔!\n");
    printf("印完不會自己");
    printf("換行\n");
    return 0;
}
//output:
//資工系桌招募新生中,女生不用繳隊費喔!
//印完不會自己換行
//

C

printf vs print

python

print("資工系桌招募新生中,女生不用繳隊費喔!")
print("預設是")
print("會換行")
print("這樣才會", end = '')
print("不換行")
#印出多項
print(3, [0, 1], "hello")
print(3, [0, 1], "hello", sep = '')
print('cindy', '0345', sep = '_')
#output:
#資工系桌招募新生中,女生不用繳隊費喔!
#預設是
#會換行
#這樣才會不換行
#3 [0, 1] hello
#3[0, 1]hello
#cindy_0345

input

a = input()
#input : hello world
print(a)
#output : hello world

b = input('please enter a number')
#output : please enter a number|
#input : 35

print(b + 5)
#Type Error : 字串跟整數無法做加法

input就是python的標準輸入,跟scanf不同的是,input只能單純把一整行輸入當作字串吃進來,比較像C中的gets

但由於吃進來的型態是str,沒辦法當作int做加法,我們要怎麼改變b的型態呢?

變數轉型

b = input()
#input : 35
print(type(b))
#output : <class 'str'>
b = int(b)
print(type(b))
#output : <class 'int'>
print(b + 5)
#output : 40

x, y = 12, 34
z = int(str(x) + str(y))
print(z)
#output : 1234

c = 1.3
d = int(c)
print(d)
#output : 1

跟C中的強制轉型很像,但python的轉型更泛用,能夠直接把數字和字串互轉

a = 'hello'
b = int(a)
#error

# ASCII值和字元互轉

print(ord('0'))
#output : 48
print(chr(97))
#output : a

bool(布林變數)

>>> 2 < 3
True
>>> 4 < 3
False
>>> 2 == 2
True
>>> 2 >= 2
True
>>> 3 <= 2
False
>>> 2 != 2
False
>>> 5 > 3 > 1
True
>>> 7 > 5 < 8 > 2
True
>>> 3 < 2 > 1
False

bool基本上就是True或是False,判斷式的回傳值都是bool,基本上跟C/C++中的邏輯相同

>>> not True
False
>>> not False
True
>>> 3 >= 2 and 3 >= 1
True
>>> 2 >= 3 and 2 >= 1
False
>>> 3 < 2 or 3 < 1
False
>>> 3 > 2 or 3 < 1
True
>>> True or False and False
???
>>> not True
False
>>> not False
True
>>> 3 >= 2 and 3 >= 1
True
>>> 2 >= 3 and 2 >= 1
False
>>> 3 < 2 or 3 < 1
False
>>> 3 > 2 or 3 < 1
True
>>> True or False and False
True
#但盡量不要寫出這種東西...

if/elif/else

year = input()
if year % 4 == 0:
    if year % 100 == 0:
        if year % 400 == 0:
            print('閏年')
        else:
            print('平年')
    else:
        print('閏年')
else:
    print('平年')

就是C中的if/else if/else,只要注意一開始提到的,python中段落是以冒號和縮排區分的就好

loops - while

i = 1
while i <= 100:
    print(i)
    i += 1

'''
output:
1
2
3
4
...
100
'''

python的loop一樣有while/for兩種,其中while基本上跟C的一樣

loops - for

for i in [iterable]:
    do event
#常見的iterable有range以及list兩種

for的使用上就有點不同,C中的for只是為方便把while中會分開寫的變數宣告,執行條件,變數增值寫在一起。python中的for則是讓變數去迭代一個可迭代物件(iterable)

iterable - range

可迭代物件就是可以讓變數從裡面一個一個的取值

range函式可以接1~3個參數,range(a, b, c)的意思就是從a開始迭代,每次加c,直到達到或超過b就停止

可以想成是C中的for(i = a; i < b; i += c)

iterable - range

for i in range(1, 7, 2):
    print(i)
'''
output:
1
3
5
'''
for i in range(1, 4):
    print(i)
'''
省略一個參數時,預設c = 1
output:
1
2
3
'''
for i in range(3):
    print(i)
'''
省略兩個參數時,預設a = 0
output:
0
1
2
'''

iterable - list

ary = [1, 4, 5, 3]
for i in ary:
    print(i)
'''
output:
1
4
5
3
'''
for i in range(len(ary)):
    print(ary[i])
'''
output:
1
4
5
3
'''

前面講過的list也是可迭代物件,迭代方式就是一個一個從list拿出來,注意C和python中用for迭代iterable本身/迭代索引值的用法差異

int ary[4]={1, 4, 5, 3};
for(int i = 0; i < 4; i ++)
    printf("%d\n",ary[i]);
/*
output:
1
4
5
3
*/
for(int i : ary)
    printf("%d\n",i);
/*
output:
1
4
5
3
*/

iterable - list vs range

print(type([0, 1, 2]))
#output : <class 'list'>
print(type(range(3)))
#output : <class 'range'>

lst = list(range(1, 10, 2))
print(lst)
#output : [1, 3, 5, 7, 9]

在python3中,range所做的事並非產生一個list,也就是range(1000000)並不會開啟1000000格記憶體空間。

不過range可以轉型成list

loops - break, continue

for n in range(2, 10):
    is_prime = True
    for x in range(2, n):
        if n % x == 0:
            print(n, 'equals', x, '*', n//x)
            is_prime = False
            break
    if is_prime:
        print(n, 'is a prime number')

用法跟C完全一樣!不過python的迴圈有個方便的else功能,在迴圈自然結束後會執行,可以取代在C中我們常常要用flag去紀錄迴圈是否是被break出來的

for n in range(2, 10):
    for x in range(2, n):
        if n % x == 0:
            print(n, 'equals', x, '*', n//x)
            break
    else:
        print(n, 'is a prime number')

與list有關的好用函式們

>>> lst = [3, 1, 2, 4]
>>> max(lst)
4
>>> min(lst)
1
>>> sum(lst)
10
>>> lst.index(4)
3
>>> lst.remove(3)
>>> lst
[1, 2, 4]
>>> lst.pop(1)
2
>>> lst
[1, 4]
>>> lst.append(5)
>>> lst
[1, 4, 5]
>>> len(lst)
3
>>> lst = [3, 1, 2, 4]
>>> sorted(lst)
[1, 2, 3, 4]
>>> sorted(lst, reverse = True)
[4, 3, 2, 1]
>>> lst
[3, 1, 2, 4]
>>> lst.sort()
>>> lst
[1, 2, 3, 4]


>>> str = "Hello my name is Howard"
>>> lst = str.split(' ')
>>> lst
['Hello', 'my', 'name', 'is', 'Howard']
>>> str = 'cindy_0345'
>>> lst = str.split('_')
>>> lst
['cindy', '0345']

自訂函式

def add1(x, y):
	return x + y
def add2(x, y):
	x += y

x, y = 3, 2
print(add1(x, y))
print(x)
print(add2(x, y))
print(x)

x, y = [1, 2], [3, 4]
print(add1(x, y))
print(x)
print(add2(x, y))
print(x)

使用方式跟C也差不多,一樣注意不用宣告函數和參數的型態,還有用冒號和縮排就好

output:
?
?
?
?


?
?
?
?
output:
5
3
None
3


?
?
?
?
output:
5
3
None
3


[1, 2, 3, 4]
[1, 2]
None
[1, 2, 3, 4]

自訂函式

def get_perimeter_and_area_of_rectangle(x, y):
    return 2 * (x + y), x * y

peri, area = get_perimeter_and_area_of_rectangle(3, 5)
print(peri, area)
#output : 16, 15

def magnitude_of_vector(x, y, z = 0):
    return (x ** 2 + y ** 2 + z ** 2) ** 0.5

m1 = magnitude_of_vector(3, 4)
m2 = magnitude_of_vector(1, 2, 2)
print(m1, m2)
#output : 5.0, 3.0

比起C,多了一次回傳多個值的功能,也多了optional argument的功能

pass

def useless():
    pass

if 1 < 3:
    pass

for i in range(3):
    pass

python中不允許一個段落是空的,不像C的段落中左右大括號中間可以是空的。因此有時候會用到pass這個關鍵字來代表什麼事都不做

大家有什麼問題嗎

  • 如果有的話現在可以問我
  • 但你們未來寫python時可能還是會遇到問題
  • 寫其他科的時候也會,資工系的課大部分都不會教你所有你該會的內容
  • 所以我要教大家一個解決問題最好的方式
  • 不管你在哪門資工相關的課都適用
  • https://stackoverflow.com/search?q=how to blablabla

謝謝大家

Introduction to Python

By Howard Yang

Introduction to Python

  • 204