[Day02] Python 程式設計概論


什麼是程式設計?

寫程式簡單來說就是下指令請電腦做事情,而程式設計則是根據需求分析,拆解問題成明確的步驟並撰寫程式語言讓電腦完成我們想要完成的任務。(例如:將網路爬蟲的資料寫到 excel 表單、判斷是否遊戲結束、將使用者輸入的資料寫入資料庫、將資料分析的結果資料視覺化等)

程式(program)就是一系列電腦指令(command)的集合。而程式設計 = 資料結構(data structure) + 演算法(algorithm)。資料結構代表資料在程式中儲存的方式,演算法代表程式執行的方法和步驟

程式設計師(programmer)是一群透過程式語言讓電腦完成任務的人,而在真正撰寫程式(programming)之前我們通常會先把程式演算法(algorithm)邏輯用筆寫下來進行分析,確保思考方向和邏輯是正確的。若是思考方向錯誤,即便程式語法(syntax)都正確,還是無法完成希望完成的任務。

演算法是一個有輸入且有輸出的解決問題的步驟,它具有明確和有限步驟且有效的特性

一般來說,在接到需求任務時我們不應該一開始就埋頭寫程式,而應該是去釐清需求和撰寫程式的邏輯和方向。通常我們會使用三種工具來進行分析:

  1. 將需求轉換成文字描述(description)
    1. 初始化計算值
    2. 從 1 累加到 20
    3. 累加完後印出結果
    4. 結束程式
  2. 將需求轉換成虛擬碼(Pseudocode):風格上接近程式碼,但不是實際的程式碼,是一種描述演算法的一種方式,有可能會用到程式碼表示方式、文字等,例如:
     # 注意以下為虛擬碼,非正式程式碼,表示從 1 到 20 累加
     # 宣告兩個變數 counter / result
     counter = 1
     result = 0
     while counter <= 20
     {
        result = result + counter
        add 1 to counter
     }
     output result
    
  3. 根據任務需求,畫出流程圖(Flow Chart):用圖示方式表達整個程式邏輯流程

學寫程式(coding)重要的是邏輯觀念和電腦科學背後運作的邏輯以及學習解決問題的運算思維,大部分情況國高中的英文和數學能力就已經夠用了

舉例來說,我們今天希望製作一個判斷是否年紀已經可以投票(假設 20 歲(含)以上可以投票)的小程式。

在真正動手寫程式前,先來寫寫文字描述

  1. 請使用者輸入年紀 => 接收使用者輸入 input
  2. 判斷是否可以投票(若使用者輸入的年紀大於等於 20 歲,程式會印出 恭喜你,你可以投票!,若年紀小於則印出 sorry, 你還不能投票呦!)=> 即為程式語言中的條件判斷 if...else...
  3. 結束程式

透過清楚明確的有限步驟,我們可以解決我們想解決的問題並產出我們要的輸出結果。

畫畫流程圖(Flow Chart),讓思路更清晰

除了文字描述外,我們還可以透過畫圖的方式來分析程式需求,讓思路更清晰,以利我們撰寫程式。

https://static.coderbridge.com/img/happycoder/606b21ee85da4c3e82be3267c1d5fb18

一般來說流程圖是由上往下執行,有開始也有結束,常見的圖示如下:

  1. 橢圓形:代表開始結束
  2. 長方形:代表執行、處理過程
  3. 菱形:代表條件判斷,做決策
  4. 平行四邊形:代表輸入/輸出
  5. 箭頭線:代表流程執行順序
  6. 圓形:代表連結多個來源的箭頭線

投票年齡判斷流程圖範例:

https://static.coderbridge.com/img/happycoder/80fae45e4b8f4ca896ad9e2277686356

開始把文字描述、流程圖轉成真正的程式碼

現在我們把文字邏輯流程轉成 Python 程式碼:

"""
我是程式碼註解:
input 會讓使用者輸入值(請輸入你的年紀為提示字元),
int() 會把使用者輸入從文字字串(string)轉為 integer 整數(input 函式取得的值為文字字串)。
age 則是變數,對應到使用者輸入的值。使用 age 就可以取出對應的年齡值
"""

# 代表接受使用者輸入的敘述式
age = int(input('請輸入你的年紀'))

# 判斷是否年紀大於等於 20 歲(整數),若有則印出 恭喜你,你可以投票!若否則印出 sorry, 你還不能投票呦

# 條件判斷,決定程式要執行到哪個區塊
if age >= 20:
    print('恭喜你,你可以投票!')
else:
    print('sorry, 你還不能投票呦!')

在 Python 中使用 # 為單行註解(註解是給人看,程式不會執行),事實上軟體工程師和程式設計師在工作時有很大一部份時間在溝通和閱讀程式碼上,實際花在寫程式的時間並不如一般人想像的多。

若是多行註解為使用 """

"""
大家好
我是
多行註解
"""

以上判斷年齡的程式若是使用 C 語言撰寫的話會是長這樣:

// 引入標準函式庫
#include <stdio.h>

int main(void) {
    // 宣告變數
    int age;
    // 註解:接收使用者輸入
    scanf("%d", &age);

    if (age >= 20) {
      printf("恭喜你,你可以投票!");
    } else {
      printf("sorry, 你還不能投票呦!");
    }
    return 0;
}

有沒有感覺 Python 程式語法很簡潔好閱讀呢?

接下來打開 repl.it 線上編輯器自己動手試試看吧!

隨堂程式練習:判斷可否投票小程式

假設今天公投通過,T 國的投票年齡從 20 歲,改成 18 歲即可投票,請協助更改以下程式碼讓他可以判斷是否使用者 18 歲即可以投票。

程式如何在電腦上運作?

事實上電腦並非如我們想像中的聰明,最早的電腦其實就是一個大型計算機,輸入資料後進過運算輸出結果。隨著時代的演進,目前電腦常見的硬體架構:CPU(中央處理器,負責運算)、Memory(記憶體)、Disk(硬碟儲存裝置)、Device I/O(輸入輸出裝置 ex. 輸入鍵盤、輸入滑鼠、輸出螢幕、輸出喇叭)等。

https://static.coderbridge.com/img/happycoder/7a19cc21cf044d3aa8bd8ee5110a0d35

我們撰寫的類似英文口語的程式碼最終會轉成電腦看得懂的機器碼(machine code),請記得一般電腦只看得懂 010101 機器二元碼!而電腦程式的運算指令(instruction)和資料(data)會儲存在記憶體(memory)中,依序給 CPU 來執行運算。由於 memory 記憶體和硬碟不一樣,硬碟是會長期儲存資料(persistent storage),memory 執行速度相對較快但程式關掉後相關儲存資料就會消失,若是需要長期持久(persistent)儲存的資料記得要存在硬碟(disk)中。

學習和程式設計師一樣的思考

運算思維(Computational Thinking)

運算思維(Computational Thinking)代表的是一種解決問題的能力,我們學習程式設計和程式語言,重點不是把語法背誦的滾瓜爛熟,而是學習分析拆解問題、辨識規律和規則、抽象化問題、設計適合的演算法等解決問題的能力,唯有練習建立像程式設計師一樣的思考框架,才能在面對真實問題時透過有邏輯的分析,將問題解決。記住,運算思維重要的是整個解決問題的過程而非運算的效能或效率。

在這個程式設計共學營中,我們不僅僅希望教會你如何使用 Python 進行程式設計解決生活上的問題,更希望你能養成運算思維,建立像程式設計師、電腦科學家一般的思考框架。這樣的訓練相信不僅是個人技能的提升,對於你的人生其他面向也會有相當程度的幫助。

程式設計流程

很多初學程式的朋友或寫了一陣子程式的程式設計師都很容易犯了一個錯誤:就是一看到問題,連思考和釐清問題需求就想跳進去解決,結果實作出來的程式和需求不符,反而浪費了許多修改時間。所以在動手撰寫程式之前,我們一定要先釐清問題和了解客戶的需求,頻繁溝通才能確保實作的程式是真正符合需求的。當然過程中必須撰寫測試和不斷除錯來確保程式的正常運作和品質。

程式語言只是一種工具,最重要的是要解決什麼問題

  1. 思考並分析問題需求(planning/thinking)
  2. 撰寫程式(programming)
  3. 測試程式(testing)
  4. 驗證除錯(debugging)
  5. 重複執行 1-4 程式設計流程直到程式符合需求且沒有錯誤

除錯 debugging 是什麼?

當程式產出結果不如預期或產生錯誤時就稱為程式有 bug,這時要做的就是除錯 debugging。過程中會需要透過假設驗證和一些開發工具的輔助去發現真正的原因(root cause)並把它修正。

一般而言程式中可能會發生的錯誤主要有三種,分別為語法錯誤 (syntax error) 、執行期間錯誤 (run-time error) 和語意錯誤 (semantic error)。

  1. 語法錯誤 (syntax error):在電腦科學中,語法錯誤是指程式的語法有誤,編譯器(compiler)或解譯器(interpreter)在詞法分析時無法將其轉換為適當的程式語言。
  2. 執行期間錯誤 (run-time error):執行時期(Run time)在電腦科學中代表一個電腦程式從開始執行到終止執行的運作、執行的時期。執行期間錯誤指的是執行時才發生的錯誤(有些檢查對於程式語言比較耗費資源,所以會在執行期才會檢查,所以有些錯誤直到執行期間才會發現)。
  3. 語意錯誤 (semantic error):又稱為邏輯錯誤,亦即語法都正確,程式也可以正常執行但結果卻不如預期。

Python 新手常見語法錯誤

在 Python 程式語言中,新手常常因為語法不熟悉而有語法錯誤,在執行時直譯器就會顯示(syntax error),這時候我們就根據顯示的線索去 debug 直到程式正確執行。
https://static.coderbridge.com/img/happycoder/176d32d6421243239a6d6cc26b7eb14f

常見的語法錯誤:

  1. 在 Python 中 == 才是比較相等意思,= 等號是賦值(assign)意思(這和一般數學的表示方式不同!)

     # 錯誤
     if age = 20:
    
     # 正確
     if age == 20:
    
  2. 在 Python 中程式格式要求嚴謹,空格縮排很重要,這是和其他程式語言比較不同的地方。在 Python 中不是使用 {} 來分隔程式區塊而是使用縮排(可以是空 2 格或是 4 格,統一就好),若發生 indent 錯誤,可能就要檢查一下程式縮排問題

     # 錯誤
     if age == 20:
     print('你可以投票!')
    
     # 正確
     if age == 20:
         print('你可以投票!')
    
  3. 特殊關鍵字後面沒加冒號(ex. if...else):

     # 錯誤
     if age == 20
    
     # 正確
     if age == 20:
    
  4. 函式未正確關閉:

     # 錯誤
     print('可以投票'
    
     # 正確
     print('可以投票')
    
  5. 字串未正確關閉:

     # 錯誤
     '可以投票
    
     # 正確
     '可以投票'
    
  6. 添加不必要的分號(Python 不用像其他程式語言需要以 ; 結尾,相對簡潔):

     # 錯誤
     age = 12;
    
     # 正確
     age = 12
    

隨堂程式練習:請幫忙 debug 除錯

想像一下今天你朋友的兒子在學校的電腦課作業要交 Python 程式作業(ㄟ朋友的兒子關我們什麼事呀),他很認真的寫完了。但執行時卻發生了錯誤,無法執行,請根據錯誤訊息,協助他完成他的作業,讓程式可以順利運行。

程式設計小撇步

  1. 變數命名:變數是暫存在記憶體空間以便接下來使用的資料,盡量使用有意義的名稱(不要使用 a, x 等比較無意義的命名),通常 Python 會使用 _ 下底線連接單字(ex. filter_data, raw_data 等)
  2. 註解:註解是程式中不會執行但是給人看的注釋
    這是 Python 單行註解 #
     # 以下會印出 hello 文字
     print('hello')
    
    這是多行註解 """
     """
     大家好
     以下會印出 hello 文字
     """
     print('hello')
    
  3. 寫測試:測試是撰寫程式一個重要環節,透過不同的測試資料可以確保程式在不同情況下可以穩定執行
  4. 程式寫不出來時怎麼辦?
    • 黃色小鴨除錯法:在軟體工程中使用的一種偵錯程式碼的方法。方法就是在程式的偵錯、除錯或測試過程中,操作人耐心地向小黃鴨解釋每一行程式的作用,以此來激發靈感與發現矛盾。
    • 起來動一動喝口水、喝杯咖啡
    • 暫時離開做其他事情和人聊聊天
    • 參考相關網路或書籍資料
    • 有禮貌地在社群請教

為什麼選擇 Python?

Python 是由 Guido Van Rossum 所開發的一種通用型程式語言,其簡潔易學和優雅可讀性高的語法和應用廣泛的特性(可以開發 Web 網路應用程式、網路爬蟲、人工智慧/資料分析、遊戲、桌面應用程式、生產力小工具等)讓許多開發者推薦為新手入門首選程式語言。此外,許多知名科技公司,如 GoogleDropboxNASAInstagram 等,都在公司產品內廣泛使用 Python 進行開發。

人生苦短,我用 Python - Bruce Eckel

Python 是一種直譯式程式語言

Python 是一種直譯式(interpreted language),亦即我們撰寫的程式碼是一行取出來轉成電腦看得懂的機器語言(machine code)後馬上執行,然後再換下一行。整個過程不需要像編譯語言(compiled language)等整個程式編譯(compiled)成可執行檔後才執行,也因此 Python 在執行效率上相比 C/C++ 等編譯式程式語言來得差(但對於程式設計師和軟體工程師來說開發應用程式的時間縮短很多)。但 Python 本身又稱為膠水語言(glue language),可以整合其他種程式語言,所以可以在程式執行速度有要求的地方呼叫 C 來加快執行效率(這部份就是進階議題了,需要進階課程來講解,這次營期課程我們不會提到,有興趣學員可以先行自行查詢)。

總結

在這堂課程中我們了解了:

  1. 什麼是程式設計?
  2. 學會了文字描述、流程圖
  3. 程式如何在電腦上運作?
  4. 學習和程式設計師一樣的思考
  5. 運算思維
  6. 程式設計流程
  7. 除錯 debugging
  8. 程式設計小撇步
  9. 為什麼選擇 Python?

若是有些部分還未能完全理解透徹的同學也不用擔心,建議在學習到後半段時再回頭再重新檢視自己的思考脈絡。

事實上,這一堂課應該可以是共學營中最重要的一堂課程,大部分的坊間程式設計課程,多半只著重在語法和應用的開發,卻忽略了學習程式設計和電腦科學背後的思考脈絡。然而,建立良好的分析思考框架和解決問題的工具箱,才是往後學習程式設計和成為好的程式設計師的重要基石。而使用文字描述和流程圖來描述整個程式設計的思考脈絡也是我們接下來課程分析問題的思考基礎。

當然,動手操作練習(程式設計如同手藝,只有練習、練習、再練習,很重要所以講三遍)才是優良學習成效的不二法門。這一堂我們同樣安排了作業任務,隨堂練習的解答也在作業說明中。同學們我們下堂見囉,happy coding :)

參考文件

  1. hierarchical memory architecture
  2. Computer components Skills
  3. 流程圖 wiki
  4. 語法錯誤 wiki

作業任務

作業任務二



問題討論區
加入問題討論
作業任務區
提交作業任務