📖研習進度

  1. 安裝Anaconda環境

  2. pipconda不同

  3. 建立虛擬環境(Virtual Environment)


Conda Commands

參考網址:https://docs.conda.io/projects/conda/en/latest/user-guide/tasks/index.html

## Creating and Removing an environment with commands
$conda create --name NCCU109_2 python=3.9
$conda remove --name NCCU109_2 --all

## Specifying a location for an environment
$conda create --prefix ./Test_envs python=3.9
$conda remove --prefix /Users/chenzhenghui/Test_envs --all

## Install Package
$conda install PKGNAME
$conda install jupyter qtconsole

## Activating juyter qtconsole
$jupyter qtconsole

## Activating an environment
$conda activate NCCU109_2

## Deactivating an environment
$conda deactivate

## Get virtual environment list
$conda env list

Python程式結構

Python程式可分解為模組(module)、敘述(statement)、表達式(expression)與物件(object):

  1. Programs are composed of modules.

  2. Modules contain statements.

  3. Statements contain expressions.

  4. Expressions create and process objects.

其中,Python裡的東西全部皆為物件!

Everything is an Object!

縮排(indentation)與程式區塊(block)

  • Python的程式敘述是以為單位,一行為一個敘述

  • Python使用空格縮排來區分程式區塊(含for loop、if-else子句等),與其他程式語言使用 {} 不同

/* C語言,縮排整齊 */
int n, r;
n = 9;
r = 1;
while (n > 0) {
  r *= n;
  n--
}

/* C語言,任意縮排的方式*/
int n, r;
      n = 9;
      r = 1;
       while (n > 0) {
  r *= n;
  n--
}
  • Python可使用空格與Tab來縮排,只要同一個程式區塊的縮排方式一致即可

  • Python官方建議以4個空格作為縮排

  • 空格與Tab(在某些編輯器看似4個空格)屬於不同縮排,故不建議同時使用

  • 建議同一個層次區塊使用相同縮排。雖然以下仍是合法編排:

if 判斷:
    for 迴圈A:
        程式區塊A
    for 迴圈B:
           程式區塊B
  • 縮排為Python語言的一部分,擁有許多好處:

    • 不會有大括弧多寫與少寫的問題

    • 程式可讀性高

    • 程式一致性高

註解(comment)

  • 在Python中以#符號後面的任何內容視為註解,並被解釋器忽略

    x = 5 # 設定變數x值為5
    x = 3 # x現在為3
    x = "# This is not a comment"

Python基礎

變數指派(assignment):=

  • Python無須事先宣告變數型態

  • 可指派任何型態的物件給Python變數

  • 變數引用(reference)物件

  • 變數在表達式使用之前,必須先被指派創建

    x = 5
    print(x)
    ## 5
    x = "Hello"
    print(x)
    ## Hello
  • Python的變數指派為貼上「標籤」或「名牌」的動作

    a = [1, 2, 3]  # 建立list,注意:list為可變(mutable)物件
    b = a
    c = a
    b[1] = 100
    print(a, b, c)
    ## [1, 100, 3] [1, 100, 3] [1, 100, 3]
    a = 1    # a(值為1)為不可變(immutable)物件
    b = a
    c = a
    b = 100
    print(a, b, c)
    ## 1 100 1
  • Python變數名稱區分大小寫,可包含任何英文字母、數字、以及底線(_),但必須以字母或底線開頭

    x = 100
    print(x)
    ## 100
    # x = 100
    # del x    # 刪除物件x
    # print(x)
    
    ## NameError: name 'x' is not defined

表達式(Expression)

x = 3
y = 5
z = (x + y) / 2
print(z)
## 4.0
3 / 2
## 1.5
3 // 2    # 整數除法,回傳小於商數的最大整數
## 1
-3 // 2   # 整數除法,回傳小於商數的最大整數
## -2

簡單內建(Built-in)型態

數值(number):int & float

  • 整數(int)

  • 浮點數(float)

x = 100    # int:整數型態
type(x)
## <class 'int'>
y = 100.0    # float:浮點數型態
type(y)
## <class 'float'>
3.14 * 2
## 6.28
1e-3 # 科學記號表達
## 0.001
1E-3 # 大寫E也可以
## 0.001
len(str(2 ** 1000000))  ## **:power,str():轉換為str,len():計算長度
## 301030
  • 混合類型時,自動升級為更複雜的型態

    type(40 + 3.14)
    ## <class 'float'>
int(3.1415)    # 截斷小數位為整數
## 3
float(3)       # 轉換整數為浮點數
## 3.0
內建數值工具
  • Expression operators:
    +, -, *, /, >>, **, etc

  • Built-in mathematical functions:
    pow, abs, round, int, hex, bin, max, min, etc.

  • Utility modules:
    random, math, etc.

進階數值函數
import math
math.pi
## 3.141592653589793
math.e ** 2
## 7.3890560989306495
math.sqrt(2)
## 1.4142135623730951
import random
random.random()
## 0.2915432629644915
random.choice([1, 2, 3, 4])
## 4
dir(math)
## ['__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'comb', 'copysign', 'cos', 'cosh', 'degrees', 'dist', 'e', 'erf', 'erfc', 'exp', 'expm1', 'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'gamma', 'gcd', 'hypot', 'inf', 'isclose', 'isfinite', 'isinf', 'isnan', 'isqrt', 'lcm', 'ldexp', 'lgamma', 'log', 'log10', 'log1p', 'log2', 'modf', 'nan', 'nextafter', 'perm', 'pi', 'pow', 'prod', 'radians', 'remainder', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'tau', 'trunc', 'ulp']

複數(complex)

1 + 1j
## (1+1j)
1 - 2J # 大寫J也可以
## (1-2j)
3 + 1j - (3 + 3j)
## -2j
(3 + 1j) * (3 + 3j)
## (6+12j)
1j * 1j
## (-1+0j)
z = 3 + 4j
z
## (3+4j)
z.real
## 3.0
z.imag
## 4.0
進階複數函數
import cmath
dir(cmath)
## ['__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atanh', 'cos', 'cosh', 'e', 'exp', 'inf', 'infj', 'isclose', 'isfinite', 'isinf', 'isnan', 'log', 'log10', 'nan', 'nanj', 'phase', 'pi', 'polar', 'rect', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'tau']
from math import *
# sqrt(-1)
# ValueError: math domain error
from cmath import *
sqrt(-1)  # sqrt函數來自模組cmath
## 1j

Inf

float('Inf')
## inf
float('inf')
## inf
float('INF')
## inf
import math
math.inf
## inf
math.isinf(float("-inf")) # OUTPUT:True. Return True if x is a positive or negative infinity, and False otherwise.
## True
math.isinf(float("inf"))
## True
float("inf") == float("inf") 
## True
float("-inf") == float("-inf") 
## True
float("inf") == float("-inf")
## False

字串(str)簡介

  • Python以雙引號(")或單引號(')或三引號(''')來建立字串

    x = "Hello, World"
    x
    ## 'Hello, World'
    x = "\tThis string starts with a \"tab\"." 
    x
    ## '\tThis string starts with a "tab".'
    print(x)
    ##  This string starts with a "tab".
    x = "This string contains a single backslash(\\)."
    x
    ## 'This string contains a single backslash(\\).'
    print(x)
    ## This string contains a single backslash(\).
    x = "Hello, World"
    x
    ## 'Hello, World'
    x = 'Hello, World'
    x
    ## 'Hello, World'
    x = "Don't need a backslash"
    x
    ## "Don't need a backslash"
    x = 'Can\'t get by without a backslash'
    x
    ## "Can't get by without a backslash"
    x = "Backslash your \" character!"
    x
    ## 'Backslash your " character!'
    x = 'You can leave the " alone'
    x
    ## 'You can leave the " alone'
    x = """Starting and ending a string with triple " characters
    permits embedded newlines, and the use of " and ' without
    backslashes"""
    x
    ## 'Starting and ending a string with triple " characters\npermits embedded newlines, and the use of " and \' without\nbackslashes'

None(None)

  • 表示代表『不存在』或是『空值』(如R語言的NULL)

  • None在Python亦代表佔位符號(place holder),用來表示資料中某一個欄位目前尚未得知具體之值,先保留該位置,之後再填值(類似R語言中NA的功能)。

None == False
## False
None == 0
## False
None == None    # None只會等於自己
## True
None is None
## True

Booleans(bool)

  • 本質上為整數int的子類別:True為1,False為0

  • 擁有不同於int型態的列印(print)方式

type(True)
## <class 'bool'>
isinstance(True, int)
## True
True == 1   # same value
## True
True is 1   # But a different object
## False
True or False
## True
True + 1
## 2
float(True)
## 1.0
float(False)
## 0.0
int(True)
## 1
int(False)
## 0

比較(comparison)

1 < 2
## True
2.0 > 1
## True
2.0 == 2
## True
2.0 is 2
## False
x = 2
y = 4
z = 6

x < y < z       
## True
x < y and y < z
## True
x < y > z
## False
x < y and y > z
## False
1 < 2 < 3.0 < 4
## True
1 > 2 > 3.0 > 4
## False
1 == 2 < 3
## False
1 == 2 and 2 < 3
## False
  • 請注意浮點數的比較:

    1.1 + 2.2 == 3.3
    ## False
    1.1 + 2.2
    ## 3.3000000000000003
    • 使用math.isclose

      import math
      math.isclose(1.1 + 2.2, 3.3, abs_tol=1e-6)
      ## True
    • 使用decimal module:有固定的小數點位數,為精度固定的浮點數。

      from decimal import *
      Decimal('0.1') + Decimal('0.1') + Decimal('0.1') - Decimal('0.3')
      ## Decimal('0.0')
      Decimal('0.1') + Decimal('0.1') + Decimal('0.1') - Decimal('0.30')
      ## Decimal('0.00')
      Decimal(0.1) + Decimal(0.1) + Decimal(0.1) - Decimal(0.3) # 預設28位
      ## Decimal('2.775557561565156540423631668E-17')
      getcontext()
      ## Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999, Emax=999999, capitals=1, clamp=0, flags=[Inexact, FloatOperation, Rounded], traps=[InvalidOperation, DivisionByZero, Overflow])
      getcontext().prec
      ## 28
    • 使用fractions module:轉換為有理數

      from fractions import Fraction
      x = Fraction(1, 3)
      y = Fraction(4, 7)
      x
      ## Fraction(1, 3)
      y
      ## Fraction(4, 7)
      x + y
      ## Fraction(19, 21)
      x - y
      ## Fraction(-5, 21)
      x/y
      ## Fraction(7, 12)
      Fraction('.25')
      ## Fraction(1, 4)
      Fraction('1.25')
      ## Fraction(5, 4)
      Fraction('.25') + Fraction('1.25')
      ## Fraction(3, 2)

Python風格與命名慣例

命名慣例

PEP 8

動態型別程式語言(Dynamic Type Programming Language)

不需變數宣告

  • Python在執行時,變數型態是在運行中自動決定,而不是透過事先變數宣告。

    • 變數創建

      變數在指派時即創建之,之後的指派將會改變已創建之變數內容。

    • 變數型態

      變數從不擁有任何與他關聯的型態訊息與限制。型態的概念存在物件本身,而不在變數名當中。只是在某個時間點上,變數參考一個特定對象而已。

      型態屬於物件,不屬於變數

      Types Live with Objects, Not Variables

    • 變數使用

      當變數出現在表達式中,他會馬上對當前所參考的物件所替代。所有物件必須在使用前輩明確定義。

      a = 100
      • 先創建整數物件100

      • 創建一個變數a,如果他之前沒有被創建下

      • 將變數a與整數物件100綁定在一起


  1. 變數(Variable)包含:指向物件的連結

  2. 物件(Object)存放在記憶體中

  3. 參考(Reference):為變數可以參考到物件的指標(Pointer)


物件的垃圾收集(Garbage-Collected)

a = 3
a = 'spam'
  • 當一個變數名被指派一個新的物件時,如果原來的物件沒有被其他變數名所引用,則之前的物件佔用的記憶體空間將會被回收。

  • Python會在每一個物件中保留一個計數器,計數器紀錄當下該物件被參考的數目。當計數器被設置為0時,這個物件佔用的記憶體就會被自動回收。

共享引用(Shared Reference)

a = 100
b = a
  • 變數a與變數b都引用了相同的物件,也就是指向了相同的記憶體位址

  • 即為『共享引用』


a = 100
b = a
a = 'nccu'
print(b)
## 100
  • 創建新的字串物件('nccu'),並創建a對此新物件進行引用。

  • 這並不會改變b的值,b仍然引用原來的整數物件3。

  • 因為intstr為不可變物件


a = 100
b = a
a = a + 2
print(b)
## 100
  • 最後的變數a引用一個完全不同的物件

  • 因為int為不可變物件


共享引用與原地修改(Shared References and In-Place Changes

)

  • 有些物件為『可變(mutable)』,如list, dictset,確實會發生原地修改

  • 在使用這些物件並共享引用時需特別注意

    因為所有的指派(assignment)都是引用(Reference)

L1 = [2, 3, 4]
L2 = L1

L1[0] = 200   # 修改L1
print(L1, L2)  # 結果L2也跟著改變
## [200, 3, 4] [200, 3, 4]
L1 = [2, 3, 4]
L2 = L1[:]    # 複製一份L1給變數L2引用
L1[0] = 300
print(L1, L2)
## [300, 3, 4] [2, 3, 4]
X = 100
Y = X
X == Y
## True
X is Y
## True
L = [1, 2, 3]
M = L
M == L
## True
M is L
## True
L = [1, 2, 3]
M = L[:]
M == L
## True
M is L
## False
L = [1, 2, 3]
M = [1, 2, 3]
M == L
## True
M is L
## False
import sys
sys.getrefcount(1)
## 1113
  • 「動態型別」特性為Python多形(polymorphism)的基礎

  • 「動態型別」是Python唯一的指派(賦值)機制