2008年4月30日 星期三

如何像電腦科學家一樣思考

◎ 前言

David Beazley 著

作 為教育家、研究者及書籍作者,我很高興看到這本書的完成。Python 是個有趣並且非常易用的程式語言,在過去幾年裡,Python 逐漸地受到歡迎。Guido van Rossum 在十多年前開發了 Python,其簡單的語法與整體感覺則是得自於 ABC,這個 1980 年代發展的教學語言。然而,Python 也被設計成可以解決真實的問題,並且也從其他程式語言如 C++、Java、Modula-3 和 Scheme 等,借用了各式各樣的特徵。正因如此,Python 最顯而易見的特色之一就是它廣泛吸引了專業軟體開發者、科學工作者、研究者、藝術家及教育家。 雖然 Python 吸引了不同社群的人士,你可能還是會懷疑:為何選用 Python?或者為甚麼教導用 Python 撰寫程式? 回答這些問題可不簡單-特別是當大眾的意見都站在,如 C++ 和 Java 這些自討苦吃的選擇這一邊的時候。然而,我想最直接的答案就是用 Python 寫程式可以單純地得到許多樂趣,並且更有生產力。

當 我教授電腦科學課程時,我希望教學題材涵蓋重要概念,又能對學生來說有趣且迷人。可惜的是,程式設計入門課程目前傾向投注過多焦點在數學抽象概念上,且讓 學生因惱人問題而沮喪,如語法、編譯以及看起來晦澀難解的規則等低階細節。儘管這些抽象及形式,對專業軟體工程師和計畫繼續學習電腦科學的學生來說非常重 要,但在一個入門性的課程採取這種方式,大部分只會使電腦科學更無趣。教課的時候,我可不想面對一整間無精打采的學生。我寧願看到他們透過探索不同的想 法,採取有創意的方式,打破成規並從錯誤中學習,以嘗試解決有趣的問題。這麼做的原因是,我不想浪費半個學期試著釐清含糊的語法問題、難以理解的編譯器錯 誤訊息,或是一個程式可能造成一般性保護錯誤的數百種方式。

我喜歡 Python 的原因之一,就是它在實做與概念上取得了很好的平衡。既然 Python 是直譯的,初學者幾乎可以立刻學會這個語言,並做些美妙的事,而不會迷失在編譯與連結的問題中。更有甚者,Python 隨附大型的模組庫,能夠應用在各種工作上,包括網路程式設計到圖形處理等。具有如此實用的重點是吸引學生注意力的絕佳方式,並且能讓他們完成重要的專案。 然而,Python 也可以作為介紹重要電腦科學概念的優良基礎。由於 Python 完整支援程序和類別,便可逐步引導學生認識程序抽象化、資料結構,以及物件導向程式設計等課題,這些全都可以應用在往後 Java 或 C++ 的課程上。Python 還向函數型程式語言借了許多功能,可以用來介紹這些以往是在 Scheme 及 Lisp 的課堂上詳細介紹的概念。

讀 了 Jeffrey 的序文,我被他的評論所感動,Python 使他看見更高層次的成就以及較低層次的挫折,而他可以工作得更快且獲得較佳結果。儘管這些評論是指他的入門課程,我有時會以同樣的理由,將 Python 應用在芝加哥大學的進階研究所電腦科學課程。在這些課程裡,我不斷地面對將大量困難的課程資料,包含在極短的九星期學季中這種讓人氣餒的工作。雖然我必定 可以承受使用像 C++ 這種語言所帶來的大量痛苦及折磨,我常常發現這種方式有著不良的後果,特別是這些課程的主題不只是關於程式設計時。我發現使用 Python 讓我能夠較為集中在實際的主題上,同時也使學生能夠完成重要的課程作業。

雖然 Python 仍是年輕、發展中的語言,我相信它在教育上會有耀眼的未來。這本書在這方向上是重要的一步。

(David Beazley,芝加哥大學,Python Essential Reference 作者)


◎ 序言

Jeffrey Elkner 著

本書的存在歸功於網路及自由軟體運動所實現的合作方式。它的三位作者-一位大學教授、一位高中老師,以及一位專業程式設計師-尚未見過面,但是我們已經能夠緊密合作,並且受到許多願意付出時間與心力的傑出人士幫助,使得這本書更臻完善。

我們認為本書證明了此種合作方式的優點以及未來的可能性,而這樣的合作架構已經由 Richard Stallman 和自由軟體基金會運作多年。

◎ 我如何及為甚麼使用 Python

1999 年,大學委員會的「先修大學電腦科學課程」(Advanced Placement Computer Science)考試,第一次用 C++。和全國各地的許多高中一樣,維吉尼亞州阿靈頓郡約克敦高中的電腦科學課程也直接受到變更語言的決定影響,我就在此所高中任教。在此之前, Pascal 是我們一年級及先修課程的教學語言。為了和過去讓學生有兩年的時間接觸相同語言的作法一樣,我們決定在 1997 到1998 學年的一年級課程改用 C++ 教學,如此我們便能銜接大學委員會對下年度先修電腦科學課程的改變。

兩年後,我確信使用 C++ 為學生介紹電腦科學,不是個適當的選擇。雖然它的確是個非常強大的程式語言,但它也是個極度難以學習與教導的語言。我發現我自己不斷地對抗 C++ 困難的語法以及處理相同事務的多重方式,結果讓我無謂地失去了許多學生。我確信一定會有更適合一年級課程的語言,於是開始尋找一個可以替代 C++ 的選擇。

我需要一個能夠運作在我們 GNU/Linux 實驗室語言,但同時也要能夠運作在大部分學生家裡的 Windows 及 Macintosh 平台。我希望它是個自由軟體,好讓學生不管收入多少,都能夠在家使用。我想要一個專業程式設計師使用的語言,並且有個活躍的開發社群。它必須同時支援程序 式及物件導向程式設計。最重要的是,它必須容易學習和教授。當我以這些條件研究過許多選擇後,Python 脫穎而出成為此項工作的最佳候選人。

我 請一位聰明的約克敦高中學生,Matt Ahrens,嘗試使用 Python。他不但在兩個月內學會這個語言,而且寫了一個叫做 pyTicket 的應用程式,讓我們的人員可以透過網路回報技術問題。我知道 Matt 無法在這麼短的時間用 C++ 完成如此規模的應用程式,這項成就和 Matt 對 Python 的正面評價,顯示 Python 是我所尋找的解決方案。

◎ 尋找教科書

我決定在下年度的兩個電腦科學概論課程都使用 Python 後 ,最迫切的問題是缺少一本可用的教科書。

自 由文件解決了這個問題。Richard Stallman 在今年稍早向我介紹了 Allen Downey 這個人。我們兩個都寫信向 Richard 表達發展自由教育資料的興趣。Allen 已經寫了本一年級電腦科學的教科書, 如何像電腦科學家一樣思考。當我讀了這本書,我立即知道我想將它應用在我的課程中。它是我見過最清楚且最有幫助的電腦科學教科書。它突顯出在寫程式時的思 考過程,而非特定語言的功能。閱讀它使我馬上變成了更好的老師。

如何像電腦科學家一樣思考不只是一本出色的書,並且它是以 GNU 公眾授權發佈,這就是說它可以自由使用,並可依使用者需要修改。一旦我決定使用 Python 後,我想到我可以轉換 Allen 這本書的原始 Java 版本到新的語言。也許我本來無法自己撰寫一本教科書,但從 Allen 的書改寫使我可以達成這個工作,這同時也證明了在軟體上運作良好的協力發展模式,也可以使用在教學資料上。

過去兩年來編寫這本書對學生及 我都受益匪淺,而我的學生在此過程中扮演了一個重要的角色。既然我夠在有人發現拼寫錯誤或是閱讀困難的章節時立即修正,因此我在課文因他們的建議而修正 時,為他們加分,以鼓勵他們尋找本書的錯誤。這麼做有著雙重的好處,一是鼓勵他們更加小心地閱讀課文,另一個好處則是讓課文由它最重要的評論者-使用它學 習電腦科學的學生-徹底審查。

針對本書後半部關於物件導向程式設計的部分,我知道我需要一個比我更有實際程設經驗的人來使它更為正確。本書在大部分時間處於未完成的狀態,直到開放源碼社群再次提供完成它所需要的工具。

我 收到一封 Chris Meyers 寄來的電子郵件,表達他對本書的興趣。Chris 是一位專業程式設計師,他去年在奧勒崗州尤金市的 Lane 社區大學開始使用 Python 教授程式設計課程。教授這門課程讓 Chris 找到這本書,而且他立即開始幫忙本書的編撰。在學年結束前,他在我們的網站 http://openbookproject.net 設置了一個指南手冊計畫 ,叫做 Python for Fun (http://www.openbookproject.net/py4fun/),他並擔任指導教師,與我最頂尖的學生一起合作,帶領他們進入超出我 能力之外的領域。

◎ 用 Python 介紹程式設計

過去的兩年裡,轉換及使用如何像電腦科學家一樣思考的過程已經證實 Python 適於教導初學的學生。Python 極其簡化程式設計範例,並且讓重要的程式設計觀念較容易教授。

課文中的第一個範例說明了這一點。傳統的 Hello, world 程式,在本書的 C++ 版本看來如下:


#include <iostream.h>

void main()
{
cout << "Hello, world." << endl;
}

在 Python 版本中,它變成了:


print "Hello, World!"

雖 然這是個平凡的例子,Python 的優點脫穎而出。約克敦高中的「電腦科學第一級」沒有先修課程,所以許多看到此例的學生是第一次看到一個程式。他們之中有些人聽說電腦程式設計難以學習 後,無疑地有一點緊張。本書的 C++ 版本總是強迫我在兩個令人不滿意的選項中選擇:不是冒著一開始就使某些學生感到困惑或恐懼的風險,解釋 #include、void main()、{ 和 } 陳述,就是頂著相同的風險告訴他們現在不必擔心這些東西,我們稍後會再講到這些陳述。課程此時的教學目標是介紹學生程式設計陳述的概念,並讓他們撰寫第一 個程式,從而介紹程式設計環境。Python 程式正好擁有進行這些事所需的所有條件,既不多也不少。

比較本書不同版本對此程式的解釋文 字,更進一步說明了這對初學的學生有什麼樣的意義。C++ 版本對於 Hello, world! 有著十三段的解釋文字;在 Python 版本中只有兩段。最重要的是,缺少的那十一段文字並非講述電腦程式設計中的重要觀念,而是述說 C++ 語法的瑣碎細節。我發現整本書都發生同樣的事情。Python 更清楚的語法使整個段落顯得不必要,而直接消失在 Python 版本的課文中。

使 用像 Python 這種非常高階的語言,讓教師得以延後談論關於機器的低階細節,直到學生擁有所需的背景知識,以進一步理解這些細節。它因此使教學能夠先解決重要的事。關於 這點的絕佳範例之一便是 Python 處理變數的方式。在 C++ 中,變數是一個用來容納東西的位置的名稱。變數至少有部份必須宣告型態,因為必須先決定它們所指涉之位置的大小。如此一來,變數的概念就與機器硬體緊密結 合在一起。變數強大且基礎的概念對初學的學生來說,已經十分困難(同時就電腦科學及代數兩個層面來看)。位元組及位址對問題沒有幫助。在 Python 中,變數是指涉某個東西的名字。這對初學的學生來說,是個更為直覺的概念,並且也更為接近他們在數學課中學到的變數定義。今年我教導變數比過去少了很多困 難,而且我花費較少的時間指導使用它們有問題的學生。

Python 有助於教導和學習程式設計的另一個範例是它的函數語法。我的學生對理解函數總是有著極大的困難。主要問題集中在函數定義和函數呼叫間的差別,以及與其相關 的參數和引數的區別上。Python 以十分美麗的語法解決了這個問題。函數定義由關鍵字 def 開始,所以我只要告訴我的學生:當你定義一個函數,由 def 開始,後面加上你所定義函數的名稱;當你呼叫函數時,只要呼叫(輸入)它的名稱即可。參數和定義一起使用;引數則與呼叫一起使用。沒有傳回型態、參數型 態,或是參考及數值參數干擾,所以現在我可以用比之前少一半的時間教導函數,學生也理解得更好。

使用 Python 改善了我們的電腦科學課程對所有學生的成效。與我教授 C++ 的兩年相較,我發現平均成功標準提高了,同時也降低了挫敗的程度。我前進得更快,並且能得到更好的成果。有更多的學生結束這門課程時,能夠設計有意義的程 式,並且對這門課所產生的程式設計經驗帶著正面的看法。

◎ 建立社群

我收到全球使用這本書學習或教導程式語言的人寄來的電子郵件。一個使用者社群已經開始興起,而且有許多人寄來可應用在附屬網站 http://openbookproject.net/pyBiblio 的資料,為這個計畫做出貢獻。

隨 著 Python 的持續發展,我預期這個使用者社群會持續並加速成長。這個使用者社群的出現,及它對類似的教育者合作計畫所提出的可能性,對我來說是執行這個計畫最令人興 奮的部份。藉由共同工作,我們能夠增進可用資料的品質,並節省寶貴的時間。我邀請你參加我們的社群並期待你的來信。來信請寄至 jeff@elkner.net。

(Jeffrey Elkner 約克敦高中 阿靈頓郡,維吉尼亞州)

OSSF::自由軟體鑄造場 - 如何像電腦科學家一樣思考

沒有留言: