2015/05/22

新書發表:Python程式設計入門

嗨,各位好,我寫了一本Python程式語言的入門書,還請多多指教。

書名:Python程式設計入門
作者:我
出版社:博碩文化(書號PG21421
出版日期:2015年3月29日
頁數:544頁
ISBN:978-986-434-005-7


自從1980年代末以來,Python程式語言經過二十多年的耕耘,蓬勃發展,已成為世界當紅的主流開發語言之一,不論是開放原始碼界和商業公司,採用Python來開發軟體專案的例子比比皆是,更有許多成功的案例,而且不論是哪個領域,諸如網站開發、機器人控制、影像辨識、數學運算等,都可見其身影,足可知Python擁有非比尋常的的彈性與能力。

回想起過去的年代,當作者還是莘莘學子之時,學校開設的課程大都為C/C++/Java等語言,而在更早之前,作者的老師們學習的第一支程式語言,多半是Basic或Pascal,時至今日,許多學校與程式設計課程紛紛轉而使用Python作為教學語言,不僅是因為其語法簡潔易懂,適合作為初學者走入程式世界的第一支語言,也因為Python擁有豐富的功能與特色,即便將來欲走向其他領域或某特定的範疇,也都能使用Python,不必耗費時間學習另一支語言。

這是一本Python程式語言的入門書,將會詳細介紹Python的語法和語意,此部份屬於基本功夫,就好像學習英語時,需要學習單字、詞性、時態、文法等等,然後加以運用依據適當的結構寫出句子,也就是撰寫程式;但光如此並不足夠,我們還會介紹程式設計的各種概念,諸如函式、遞迴、閉包、物件等,並且會解說程式執行的抽象模型,透過該模型,思考寫下來的程式碼(死的)在執行時的動態交互作用(活的),如此一來,方能通透明白。

Python目前分為2.x版與3.x版兩個系列,彼此並非完全相容,換句話說,某些2.x版舊程式無法給3.x版執行,反之亦然;雖說3.x版較新較先進,但仍有很多人使用2.x版,仍有眾多的2.x版舊程式,所以本書將會同時兼顧,當有差異處時將會特別註明。以2.7、3.3、3.4版為主,這也是目前最新最普及的版本。

學習資訊科學相關知識時,免不了還是需要英文,因為許多第一手資料與文件,都只有英文,所以本書會放入英文詞彙,為了避免搞混,將會多次出現中英並呈,若原詞彙沒有適當且眾人公認的適當譯詞,或是直接使用原詞彙更顯得清楚明瞭時,將會直接使用原來的英文詞彙。


章節大綱:

第1章,介紹電腦的硬體與軟體,說明程式語言在其中扮演何種角色,簡述Python歷代版本的演進差異,然後下載並安裝Python實作,準備好開發環境,然後才能開始學習Python語言。

第2章,真正開始動手撰寫Python程式,從基本概念開始講起,介紹Python直譯器、何謂名稱與物件、指派的意義、各種運算式與述句、基本的資料型別、迴圈、函式、程式庫模組等。企圖以一章的篇幅介紹必備的基礎知識,有了這一章為底,接下來就可深入,繼續探究Python的各個面向。

第3章,介紹數值型別,包括整數、浮點數、複數、布林等等,以及可用的運算,介紹與數值相關的概念,譬如加總、平均、兩數的關係等等,數值是程式設計的基礎,說到底,電腦裡的所有資料終歸是一堆0與1、也就是數值罷了。之後會介紹具備特殊用處的十進位數和分數,以及整數的位元運算。

第4章,介紹Python的主力容器型別:序列,以及相關的迭代概念,這是一種一個接著一個、具備順序性的資料結構與操作方式,Python最重要的序列型別:序列,便是其中之一,許多議題與功能皆圍繞著串列打轉,譬如可迭代者與迭代器。除了串列外,還有元組與字串,並且介紹字串格式化。

第5章,介紹序列型別以外最重要的容器型別:字典,這是一種具備映射形式的的資料結構,每個元素都是所謂的鍵值配對,本章會介紹雜湊、集合等相關主題,最後簡介具有預設值和具有順序性的特殊字典。

第6章,函式是一門大學問,此章將從基礎逐步介紹函式的裡裡外外,包括如何定義、參數的傳遞、回傳值等基本知識,以及可被呼叫者和可視範圍等概念,並會以詳細的圖示解說何謂命名空間與環境,藉以了解遞迴、閉包、高階函式等進階主題,最後介紹直接由Python語法支援的產生器和延遲綁定的概念。

第7章,本章主題包括資料與編碼,重點放在檔案開啟與文字檔案,將會詳細解釋何謂文字編碼系統,期望能掃除此方面的疑惑,搞清楚底端的二進位資料只不過是一堆0與1(或說是一堆數字),須經過解釋後才具備意義;檔案是種抽象概念,不一定指硬碟裡的檔案,也可代表網路連線或其他資料讀寫來源。

第8章,認識的工具越多,便能根據狀況使用最適當的工具來解決問題,此章介紹串列和字典以外的其他容器型別,包括具名元組、雙向佇列、模組heapq、ChainMap、陣列等等。

第9章,函式實在太過重要,所以此章再談函式,再次深入探討,主題包括遞迴、尾呼叫、裝飾器、函數式程式設計、延遲執行等。

第10章,模組是管理大型軟體的重要利器,Python程式就是由模組所組成,本章介紹如何模組與套件的概念,如何建立模組,以及各種匯入模組並使用的語法,如何尋找、安裝、使用別人開發好的模組。

第11章,雖然至此章才介紹物件導向程式設計,但我們早已使用各種型別的物件撰寫程式;本章將介紹物件導向的主題,包括定義類別、封裝、繼承、重載、覆寫與多型,也會介紹多重繼承與後設類別。

第12章,現代程式語言碰見錯誤、無法執行、意外狀況時,都會提供一套異常處理機制來讓我們著手處理,本章介紹如何引發異常、該怎麼捕抓異常、如何自行定義異常類別。

第13章,學海無涯,此章將列出讀完本書後,接下來可進一步探索研究的主題。

附錄A,分類列出Python內建函式。

附錄B,概略列出Python 2.x與3.x版的差異。

附錄C,ASCII字元表,簡述ASCII和其在今時今日的用處,以及與其他文字編碼系統的關係。

附錄D,參考資料與學習資源,包括Python官方網站裡最常使用的頁面,學習Python的書籍著作與線上教材網站,程式設計的論壇、Q&A討論區、社群以及擷取最新資訊的新聞網站,並列出幾個不錯的練習題網站,藉以磨練寫程式與思考的能力。


原始碼:

書裡所有的原始程式碼檔案,都已上傳至GitHub,可自由下載,直接點按網頁上的「Download ZIP」,便會將所有檔案打包成zip壓縮檔下載,或自行使用git指令下載;章節內文中都會註明相對應的檔名,此外,某些練習題需要的輔助檔案,也一併放在此處。


勘誤表:

若發現任何錯誤,還請留言告知,謝謝。

日期:2015.04.13
嚴重程度:中
位置:第27頁,第1行。
原文:因為Python有可變物件(int、float、str)與不可變物件(list)之分
修正:因為Python有不可變物件(int、float、str)與可變物件(list)之分

日期:2015.04.16
嚴重程度:中
位置:第26頁,下方程式碼區塊的第2行、第3行、第6行、最後一行。

原文:>>> weight = 177          # 身高
修正:>>> height = 177          # 身高

原文:>>> height = 68           # 體重
修正:>>> weight = 68           # 體重

原文:>>> li4 = [name, weight, height, title, langs]
修正:>>> li4 = [name, height, weight, title, langs]

原文:['Frank', 185, 75, 'engineer', ['C', 'Python']]
修正:['Frank', 177, 75, 'engineer', ['C', 'Python']]

日期:2015.04.19
嚴重程度:小
位置:第24頁,小節「return述句」的第一段。
原文:但可回傳tuple物件,所以可把許多物件放在tuple裡,
修正:但可回傳容器物件,所以可把許多物件放在tuple或list裡,

日期:2015.04.30
嚴重程度:中
位置:第57頁,第三個程式碼區塊的第5行,註解
原文:任何數的0次方都是0,包括0
修正:任何數的0次方都是1,包括0

日期:2015.05.05
嚴重程度:中
位置:第236頁,程式碼區塊的第5行
原文:return n * fact(n)
修正:return n * fact(n-1)

日期:2015.05.05
嚴重程度:中
位置:第263頁,第一個程式碼區塊最後一行的註解
原文:# 印出0、5、15
修正:# 印出0、5、10

日期:2015.05.05
嚴重程度:中
位置:第263頁,第二個程式碼區塊,第1行跟最後一行的註解

原文:x+n
修正:x*n

原文:# 印出0、5、15
修正:# 印出0、5、10

日期:2015.05.12
嚴重程度:中
位置:第36頁,第一個程式碼倒數第二行
原文:>>> li0 or li2
修正:>>> li1 or li2


底下是一般性質的文句修改,嚴重程度都是「小」:

日期:2015.04.16
位置:第71頁,2.7節中的第2小節標題。把全形冒號改成半形冒號。
原文:忘記冒號「
修正:忘記冒號「:

日期:2015.04.19
位置:第49頁,小節「break述句與continue述句」的第1行。
原文:使用迴圈述句(包括while與for)時,有時處理到某輪時,
修正:迴圈述句(包括while與for)處理到某輪

日期:2015.04.19
位置:第52頁,下方程式碼區塊的上面那一段。
原文:函式定義完成後,便可使用它,
修正:函式定義完成後,

原文:函式呼叫屬於運算式
修正:函式呼叫在Python語法中屬於運算式

原文:在括號內傳入適當的參數
修正:在括號內傳入適當的參數

日期:2015.04.30
位置:第59頁,最後一行
原文:呼叫boo()可得知某物件代表的真假值。
修正:呼叫bool()可得知某物件代表的真假值。

2015/05/21

Raspberry Pi:溫濕度感測器DHT11

很快速地嘗試使用溫濕度感測器DHT11,可量測相對濕度20~90%,誤差±5%;溫度0~50℃,誤差±2℃。

電路圖如下:

然後安裝Adafruit寫好的模組與範例程式,有C也有Python,嘿。

先安裝所需套件:
$ sudo apt-get update
$ sudo apt-get install build-essential python-dev

然後下載,進入該目錄:
$ git clone https://github.com/adafruit/Adafruit_Python_DHT.git
$ cd Adafruit_Python_DHT

安裝:
$ sudo python setup.py install

接著就能讀取DHT11了,執行寫好的範例Python程式:
$ cd examples
$ sudo ./AdafruitDHT.py 11 4
Temp=27.0*C  Humidity=81.0%

其中參數11代表DHT11,4代表我把它接到Raspberry Pi的GPIO 4。


參考資料:

2015/05/13

Raspberry Pi與Java 8:Hello World

嘿,我好久沒寫Java的程式,聽說Raspberry Pi/Raspbian已預設安裝Java 8(套件名oracle-java8-jdk),來試試看吧。

首先是簡單的Hello World,程式碼如下:

public class HelloWorld{
        public static void main(String[] args){
                System.out.println("Hello, world!");
        }
}

儲存為檔名HelloWorld.java,然後進行編譯:

$ javac HelloWorld.java

得到HelloWorld.class,然後執行:

$ java HelloWorld
Exception in thread "main" java.lang.UnsupportedClassVersionError: HelloWorld : Unsupported major.minor version 52.0
        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClass(ClassLoader.java:643)
        at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
        at java.net.URLClassLoader.defineClass(URLClassLoader.java:277)
        at java.net.URLClassLoader.access$000(URLClassLoader.java:73)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:212)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:205)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:323)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:294)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:268)
Could not find the main class: HelloWorld. Program will exit.

嘿,怎麼會這樣呢?這麼簡單的程式碼也出錯?查詢javac與java的版本後,

$ javac -version
javac 1.8.0

$ java -version
java version "1.6.0_34"
OpenJDK Runtime Environment (IcedTea6 1.13.6) (6b34-1.13.6-1~deb7u1+rpi1)
OpenJDK Zero VM (build 23.25-b01, mixed mode)

發現兩者不同,所以問題應該是程式被編譯為1.8版,但執行環境(JRE、JVM)卻是1.6版,於是無法執行。嗯,怎麼辦呢?試著以參數指定版本吧:

$ javac -source 1.6 -target 1.6 HelloWorld.java
warning: [options] bootstrap class path not set in conjunction with -source 1.6
1 warning

$ java HelloWorld
Hello, world!

哇,成功囉。

嗯,不過我想玩Java 8的新功能與新特色啊,拜過孤狗大神後,到Oracle JDK的網頁,下載JDK 8 for ARM,我下載的是jdk-8u33-linux-arm-vfp-hflt.tar.gz,放在家目錄裡,然後進行底下的步驟:

$ sudo mkdir -v -v /opt/java

$ sudo tar zxvf ~/jdk-8u33-linux-arm-vfp-hflt.tar.gz -C /opt/java

解壓縮並把所有東西放進/opt/java裡的子目錄jdk1.8.0_33,此時可刪除原先的壓縮檔。然後是告知系統我們想要使用剛剛安裝的Java版本。

$ sudo update-alternatives --install "/usr/bin/java" "java" "/opt/java/jdk1.8.0_33/bin/java" 1

$ sudo update-alternatives --set java /opt/java/jdk1.8.0_33/bin/java
update-alternatives: using /opt/java/jdk1.8.0_33/bin/java to provide /usr/bin/java (java) in manual mode

查看版本,都是1.8囉。

$ javac -version
javac 1.8.0

$ java -version
java version "1.8.0_33"
Java(TM) SE Runtime Environment (build 1.8.0_33-b05)
Java HotSpot(TM) Client VM (build 25.33-b05, mixed mode)

另外,有些軟體需要環境變數JAVA_HOME,請編輯~/.bashrc,加入:

export JAVA_HOME="/opt/java/jdk1.8.0_33"
export PATH=$PATH:$JAVA_HOME/bin

耶,趕快來玩Java 8吧。


參考資料: