在一場學長的演講中,聽到了以下這麼一段話(大略的意思,並非原文呈現):
改變世界的方法有很多種,就算只是躺在床上,只要你有在呼吸,就是在改變地球的碳循環,所以不要認為改變世界是一件很困難的事。但重點是,要如何「快速」的改變世界?
學長的議題是在談論 open source,參與 open source 來改善世界上的軟硬體,例如:當你成為 Linux 貢獻者時,你就改變了世界上大部份的軟硬體,這世界上有許多裝置都是以 Linux 為核心。
不過,我並不是 open source 的專家,所以這次議題不是在 open source。我想說的改變世界的方法是-教育。但講教育實在太崇高了一點,所以還是談論教導與學習就好,但我不是老師,所以我只談論助教這個職位。
在我大學四年,也修了不少課程,這些課程中其實遇到了不少「爛」助教。我所認為的「爛」,其實就只有「一問三不知」這一點,當然,每個人認為的「爛」可能都不一樣,像現在應該不少學生覺得我就是爛助教。我個人是非常不喜歡爛助教的,本身被不太會寫程式的助教亂扣分數,理由只是因為他看不懂我的程式碼。另外,有一次在 CLI 下制作了選單式的 UI 以方便助教操作,當然也是為了加分。但最後我並沒有被加到分,理由是我的 UI 沒有上色,不算 UI,還開了另一個人更簡陋的 UI 但不過上了色的跟我說這才有加分…。還有一次是,他說我沒有防呆他可以亂輸入東西讓我程式當掉所以要扣分。好吧,這點或許是我的錯,做防呆應該算是寫程式的 common sense 吧。
但是,我也遇過不少很厲害的助教,課程上問他們問題,都可以給我很精闢地解答。我覺得這些人對我的成長幫助不少,我也希望有一天我也能成為那樣的人。我個人認為,系上的助教程度實在參差不齊,而最主要的原因是,這些助教多半是開設該課程的老師的研究生。
為了想當個對學生有所幫助的助教,於是我在去年向開設「程式設計(二)」的老師毛遂自薦,希望可以擔任他課程上的助教。該課程內容是 C++ 程式設計,我自認為我的程度應該足以教導大一新生,並令他們有所學習。那是我第一次擔任助教一職,但老實說我覺得我並沒有很用心在擔任那一次的助教,可能過於自負認為自己不用特別準備就足以應付學生們了。連派給學生的作業其實我也沒寫過,只能用已知的概念來回答學生們的問題。
第二次擔任助教是上學期,擔任「網頁程式設計」的助教。我本身其實也沒寫過什麼網頁,只是對寫網頁有些興趣,看了還算不少的相關資訊,當初實習時也是在一間做社群網站的新創公司實習,所以有碰過一點點,但自身能力不足所以也幫不上什麼忙。那次擔任助教可以說是比擔任「程式設計(二)」時還認真一點,當時覺得老師教的東西略顯不足,課後的練習也太過了無新意,有許多根本就僅僅是複製投影片上的程式碼就可以完成。於是花費了整整一個晚上到天亮得時間,準備了份簡報來提供學生們一些新知(如:HTML5)。在構思課後練習題時,也都出比較需要學生多靠自己去找答案的習題,而不是僅僅複製投影片的程式碼就可以完成的。不過,就我準備簡報給學生聽那次來說,其實有在聽的很少,許多人還是想盡快完成課後練習儘快下課,老實說,是有那麼一點灰心。但是,也有學生跟我反應,他覺得我出的習題還有那次簡報讓他學到不少東西,也帶給了我一絲溫暖。
而這學期是第三次擔任助教這個職務,課程為「程式語言」,這大概是我最灰心的一學期了。老實說,我本來並沒有打算再擔任助教的,因為這堂課程的內容老實說我覺得我並不熟悉,當初大二在修這堂課時,也是渾渾噩噩的就通過了,甚至連作業出的 Scheme 與 Prolog 都不是自己寫的。但最後還是很不知所以然的接下的助教一職,其實感覺是很興奮的,知道可以學習 functional programming 跟 logical programming 著實令人振奮啊!我也希望學生可以藉由這堂課程體會到 functional programming 與 logical programming 的有趣之處,加上我希望我不會成為「一問三不知」的助教,作業內容也花費我不少時間來構思,本身也跟著學生一起學習 Lisp 與 Prolog。身為一個研究生,我這學期的重心完全不在研究上,也不在自己所修的課程上,而是在這學期所擔任的兩門課的助教上。一門是 ACM-ICPC 的培訓,而另一門則是這堂「程式語言」。這學期本來老師預期會教導三個程式語言,分別是 Lisp、Prolog 與 Ruby。不過,Ruby 是希望由我來上,可是我不會 Ruby 這昂貴的語言,只會一點點的爬說語 Python,所以第三個語言就改成 Python 了。而作業也預計是每個語言都派一個,但是後來跟一位學長討論過,他認為一學期要學三個語言只會讓學生什麼都三個學不好,所以最後一個 Python 決定改成 Lisp。反正 Python 其實寫法還是跟 C/C++ 這類的 immperative programming 差不多。而 functional programming 近期隨著平行化技術的進步,漸漸的又掀起熱潮,而 Prolog 在人工智慧的領域一直有著不敗的地位。但這堂課重點不是變成 Lisp 或是 Prolog 高手,而是希望學生能以不同的思維模式來思考問題,不要被 imperative programming 給侷限了。因次在作業上,我也希望不要設計的太過簡單,導致作業完成後也沒學習到什麼。而且,我一直認為「程式語言」是可以自學的,當你學習過一種程式語言後,應當有自行學習其他語言的能力。不過,學習一個程式語言的方法,除了「Learning by Doing」,也別無他法了。接下來,來談談這次擔任助教一職備受爭議的幾件事。
作業
Lisp - convert infix expression to post expression
其實我應該出中序轉前序才是,畢竟 Lisp 的結構就是前序啊!出這個作業的目的是,不希望出太過簡單的題目,而導致大家寫完作業後,對 Lisp 還是沒什麼概念。
而太過簡單的題目,真的無法學習到什麼,所以我決定出個至少需要些回圈控制與條件控制的題目,但又不希望大家卡在演算法的部分,所以出了個他們在大二上的資料結構寫過的作業,只是改成用 Lisp 實現罷了。
Prolog - sudoku solver
Prolog 是個邏輯推論語言,我想藉由 Prolog 強大的邏輯推論能力,拿來解數獨應該滿適合的。因為數獨是俱有固定邏輯規則的益智遊戲,我想只要能給予 Prolog 適當的推論條件,應該可以借助其強大的推論能力推算出數獨的解!
Lisp - weather forecast
這個是本來要用 Python 出的作業,但前面也提過決定用 Lisp 的原因了。想說寫程式如果盡寫些用不到的東西,是無法提高學生的學習動機的。如果,他們能寫出自己用得到的工具,應該可以讓他們體會到寫程式讓生活更便利這件事,進而喜歡上寫程式,或是認真的想把寫程式作為一技之長。
而且跟學長討論時,他提到了「駭客與畫家」這本書,Paul Graham 就是利用 Lisp 來編寫網頁程式,因此我想或許拿來處理序列資料還滿合適的,所以就繼續採用氣象預報作為作業,雖然學長希望我讓他們用 Lisp 寫 Lisp 的直譯器!
不過雖然說得好像是用 Lisp 寫個 web crawler,不過其實也沒這麼複雜,為了減少學生的負擔,我也幫他們找好了 http request 與 html parser 的套件,以及方便進行套件管理的 quicklisp。也提供了一個使用範例,將網頁資料轉換為一個有結構性的 list。基本上學生只要把我範例的網址改成氣象局的,就可以得到轉化成 list 後的預報資料。所以其實作業就只是在處理一個 list 罷了,只要找出要求的資料的位置即可,已經算簡化不少了。
以上三份作業,分別給了 3 週的時間完成,另外,第 4 週給予補交機會,但成績打七折。而三份作業也讓我跟老師被一些學生罵翻了,有學生認為出這些作業根本是認為他們只修習「程式語言」這門課,都沒有其他課程要修。有學生甚至說這們課要他們只花三週就把學會一個程式語言還要寫出一個很難的作業。我想我有幾點需要提出:
首先,作業難度我個人是覺得沒有那麼難啦,都是我跟老師討論過覺得難度適中的作業了。為了親身體會作業的難度,我也跟學生說助教也會一起寫,跟著大家一起趕 deadline,就我親身下去寫作業,我想給予三週的時間是非常適當的。只是大多人,都在最後一周才開始寫作業,當然學生也有其他課程,前兩週都排了其他課程的作業。但是,時間規劃這等事兒,應該不是老師跟助教的問題我想。我覺得啦,一個人會選擇最後一周開始寫作業,就表示他認為他有把握可以在一周內完成,最後完成與否,應該是自己要為自己負責。
再來,是否真的只給與三週學習 Lisp 與 Prolog 呢?Lisp 與 Prolog 都是在作業宣布之前就教了,不該說是只給三週學習然後寫出作業吧?!是你自己決定作業宣布後才開始學習並寫作業吧!
確實,今年的作業跟以往比較起來,難度真的提高不少,不再是不到 10 行就可以解決的作業了。
加分
另外,因為學生反應 Lisp 與 Prolog 難以掌握,怕無法順利通過這堂課,加上老師說期末不會調分,所以希望老師可以出些加分的作業。雖然說這樣還是變相的調分啦,但至少是要學生自己努力來掙得這加分機會,而不是不用付出就可以加分。所以額外出了三個加分作業,分別是:
Lisp - prime between 1 and 1000
這個是老師上課上到一半突然就派出的加分,希望讓學生多多練習 Lisp!
C++ - negative effect for bitmap
基本上就是用 C++ 來處理 bitmap 圖檔,計算出強度的 histogram 以及進行負片處理。這其實是我大一的 C++ 作業,不過要進行的處理可多了…,所以我個人是認為這個加分應該非常容易。網路上資料也非常多,只要細心一點要拿到這個分數應該不難。
我覺得這個作業的有的簡單的目的,就是要學生學會以二進位的方式讀寫檔案,本身看過有研究生連二進位讀檔是什麼都不知道,但除了純文字檔案外的檔案基本上都需要以二進位的方式來讀寫,所以也算是個基本技能了。
而在進行二進位檔案讀寫時,就需要非常注意各個位元組的位址以及其代表的意義,位址一旦有所偏差,所讀取到的檔案內容也將會有錯誤,或是寫入的檔案會發生問題。因次在閱讀 bitmap 標頭規範時就需要細心閱讀,以免發生錯誤。
在我宣布完作業內容後,一下課就聽到有學生在抱怨「這個加分題比作業還難。」
Python - weather forecast
因為有學生向老師提出 Lisp 他真的無法掌握,希望老師能出 Python 的選項當作業。不過要是這麼做的話,我想大概會有三分之二以上的學生都不會選擇用 Lisp 寫了吧…。所以我決定把它作為加分題之一,Python 網路上的資源更是豐富,可使用的套件也非常多樣,所以我就不提供該使用什麼套件了,畢竟這樣反而限制的 Python 的使用!而且其實完全不需要用到第三方套件就是。
除了這些加分外,老師也提供了參與課堂討論與課堂報告的加分方式,這都是還滿不錯的方式,學生至少需要付出些努力才能掙得這些分數。而且台灣學生不擅長討論,藉由分數誘導的方式姑且不論對與否,但就這學期的成果來看,我認為真的有讓學生們願意發問與回答他人問題。而報告的部分,由於有學生期末成績目前不理想,希望老師可以給予補救機會,於是老師讓我想了些主題給他們報告,我是選了幾個近幾年比較熱門的語言以及 framework 給他們選擇,讓所有學生更能接觸到這些平常比較碰不到的東西。因為老師有明說報告太差的話無法加分,雖然我報告當天沒有到場,但據老師所言,報告的效果也非常不錯,許多同學都非常用心的準備。而且老師也有規定要 live demo,所以不好好研究一下,live demo 肯定出包的,更何況大師們 live demo 都會出包了。
不過,給了許多的加分機會,卻有學生直接在網路上謾罵「程式語言教授一直加分一直加分一直加分,看不慣這種做法的教授。」另外,也有人認為「出加分題只是加重學生負擔,畢竟會寫的人就會去寫,不會寫的還是不會去寫。」
先針對第一句,這接加分機會有非常大的一部份都是學生要求來的,而且加分機會是人人都有的。想來想去我只想得到一種心態來解釋這句話-「希望那些目前成績不理想的都被當,少數人通過就好。」其實,我本來也是覺得成績不理想就應該要當掉,但老師跟我說教學的目的不應該是當掉學生,而是要給他們有所成長,所以願意給他們這些機會。在嚴格要求學生的過程中,我似乎都差點忘了這一點,我想這部分我真的做得不太好。
而第二句,他的意思是「會去寫加分題的人,出再多都會去寫,而不會去寫的人,出再少也不會去寫,因此認為出這些加分題只是在增加那些會去寫加分題的學生的負擔。」雖然這句話,我也很認同,不過會去寫的人或許真的成績不太好(喜歡寫程式的人成績不見得都很好),所以非常需要這些分數來通過這門課。如果真的覺得是負擔,由於是加分,如果分數已經達到及格標準是可以選擇放棄的,不放棄那應該也屬於自身在時間規劃上的問題了,而分數未達及格標準的同學,本身就應該會自己沒拿到及格的標準而付出些責任,我想也沒什麼好抱怨的。
其他
I/O 格式限制
在作業的規定上,我規定滿多格式上的要求。之所以這樣規定是為了讓我能夠直接編寫 script 進行自動化的批閱,不符合規定的會斟酌扣分。我個人認為這樣的要求是非常合理的,未來同學們多少都會有機會使用到不同服務所提供的 API,API 都會有要求的 I/O 格式。如果因為不遵守這些 I/O 格式而導致工作無法完成也不可能跟主管說:「是 Google Maps API 格式規範的問題,不是我的問題。」
為了避免學生們忘記格式上的處理,也特地發公告進行提醒。但卻有學生寄信來給我,說我公告的太晚了,希望能彈性處理,要寫個這樣的程式應該很簡單吧!我覺得是滿簡單的啦,只是接下來這一句是我比較不能接受:
有程式比賽經驗的人應該深受其害吧,那何苦當個加害者呢?
加害者…有這麼嚴重嗎?雖然事後這位同學是開玩笑地,只是不署名的方式既這封信給助教,實在令人覺得是封黑函啊!
網路 PO 文
前面有提到有學生在網路上抱怨,透過轉貼而看到那些抱怨,的確的滿生氣的因此我將該貼文也轉帖到我的 Facebook 上。有許多人認為我這樣的方式不妥,不該公佈抱怨的來源。老實說,我個人也認為我的確是有點情緒化了,但我覺得既然願意貼在網路上公開的與人分享自己的抱怨,不就是希望給別人看到嗎?雖然我想他是希望他人也能認同他的抱怨,簡單說就是討拍,只是沒想到會被助教看到,甚至是老師看到。
有勇氣公開抱怨,就該有勇氣承擔責任。成績都公開透明的處理,實在不需要擔心成績被搞掉。但主觀印象,我想就無法改變了。
在寫這篇文章的同時又回去看了看那位學生怎麼寫的,沒想到竟然還有後續,現在有了三字經、腦殘等字眼且仍舊是公開訊息。更酷的是還有他跟我的信件來往內容也公開,我想我只能說它「真男人」。看了看下面的回應也有趣,助教 PO 學生動態叫做公開批鬥,學生使用激進的字眼辱罵助教與教授算是…呵呵。
要學太多語言
有人說「一學期要學三個語言,實在吃不消」,不過我倒真的想澄清一下。只有兩個好嗎?明明就只有 Lisp 跟 Prolog,Python 只是額外補充的罷了,而且是因應學生要求希望可以出個 Python 的加分作業才會有該作業的存在。
而 Lisp 與 Prolog 這兩個本來就是這門課程所該學習的內容,程式語言這門課本來就是在講述程式語言,而這兩個語言的思維邏輯與常見的語言不相同,所以才會需要學習。要是能就只是教導命令式語言的話,那其實不太需要開設這門課。但是,「程式語言」這門課程是否需要是必修這又是另外的話題了,而且也不是我所能決定的。只是,既然擔任了這門課程的助教,我相我有義務與責任需要讓你們學會這兩種不同思維的程式語言,也因此派出了不同於以往的作業。
抄襲網路
這大概是該學期中引起最大爭議的事件。事情是這樣的,在 Prolog 作業中,有許多同學的程式碼在扣除 IO 部分後與網路上的程式碼相似度有 90% 以上吧。而這些同學的作業成績都被我打為 30 分,就當作實作 IO 的分數。為什麼有爭議呢?因為我只有說不能抄襲,但大家應該都會覺得是不能抄襲同學而已,殊不知網路也不能抄襲。而且我就說過,在詢問問題之前,請先「Search The Friendly Google」或是「Read The Freindly Manual」,就因為第一句話所以學生們認為網路資源是可以直接使用的。
但我想抄襲的定義就是「不是自己做的,是拿別人做的」。直接拿網路上的程式碼進行些微的修改,這些修改是改變數名稱改程式排版,難道這樣就表示已經會寫這個程式了嗎?或許你也可以說你只是參考而已,但參考也要附上出處啊!就我批閱完作業後,真的參考的只有一個學生,因為他有附上出處。也有許多人認為,因為一開始就參考了那份程式碼,導致思路完完全全被受限,這我能理解,所以開放了時間給學生來 live coding,如果寫得出來那就代表你真的會,那麼分數會給你 60 分及格。而且其實,就連最後沒寫出來,但也完成不少的同學我也都給及格了。
相信許多人都會使用網路上的程式碼,就連我也不意外。但是網路上的程式碼或多或少都是隱藏的危險的,直接拿來用是否安全呢?就我個人來說,我一定會瞭解該程式碼的內容才會進行使用,並且一定會自己重新輸入一次。一個原因是,在網頁上進行複製時,往往會有不如人意的格式跟著被複製了。另外就是,自己重新輸入一遍也更能掌握對這份程式碼的熟悉度。
是說在我公佈成績後,立馬就看到有同學在 Facebook 上貼出我當初寫上「Search The Friendly Google」那段話,似乎在嘲諷我叫他們 Google 卻又不能抄襲。而前面提到的那位在網路上謾罵的同學也滿有趣的,竟然說「那個東西超級難想…在加上期末大暴死期間,有誰不會抄code呢…」,有沒有這麼合理?!還說當初是我自己要他們上 Google 找資料的,結果不能參考網路上的資料…,抄襲跟參考不一樣啊!!
作業批改緩慢
在成績繳交出去後才得知有學生認為我作業批改的緊度太過緩慢,我想我就在這邊做個解釋吧。從作業三說起,作業三我曾經批改過了一次,但全班及格的可能不到 10 個吧,不過當時還沒測試過 Windows 上的程式碼。我也公告說有部分還沒批閱完成,但就有了不少抱怨…。因此隔天上課我讓每個有問題的人來說他們的問題,有不少是格式問題、有些則是無法使用 EOF 作為結束、甚至還有不滿足作業要求的…,於是我決定將作業三全部重新批改,並放鬆標準且盡可能給予分數。由於有 140 多人修這門課程,加上我要放鬆標準,這表示我需要看每一份程式碼並執行每一份程式,再者還要部分給分,我準備了 10 組測試資料來使用。深為研究生,我也是有課要上有論文要報告,實在無法把時間全花在上頭了。而作業四與作業五都延期到 6/23 繳交,而我自己本身也有期末,加上接下來一周都要到台北參加與自身研究相關的人機互動工作坊,因次在這之中僅能斷斷續續地進行部分批改。而 7/7 是加分題的繳交期限,我也是熬夜馬上批改完畢,在 7/8 將所有成績公佈。而學校前幾天才臨時寄信告知,這學期成績一定要在 7/10 送出,由於許多家長反映學校成績出來的太慢。當然我也不希望 7/8 才公佈成績,7/10 就送出去,但真的太突然以至於無法給讓更多學生有補救的機會。
結語
起初我確實是抱著相當大的熱忱來擔任助教這一職位,不過隨著付出換來抱怨的過程中,我承認我確實對於這些學生們有了不悅的態度。有不少學生認為我很兇,不敢問我問題,我想這是我需要改進的地方,不該因為少數學生的抱怨而遷怒到其他學生身上。也有人認為我都會叫他們去 Google,因而不敢問我問題,不過這一點我確實是要讓大家明白,在詢問問題時,不該只是一味的要求他人給予答覆,也要自身有過努力。我之所以會如此要求的緣故是,太多問題都是我直接放上 Google 搜尋就在第一頁能找到答案了。
另外,我想我是個高標準的助教。或許不是每個人都對於這個科目有興趣,不過我想身為助教我有責任幫助系上訓練出優秀的學生,並成為優秀的工程師。若是我降低了標準,那麼豈不是對不起系上,對不起替學生繳學費的父母們。
最後,這次助教當下來,最深刻地感受是「千萬別想滿足所有人」。在這個世界上,什麼樣的人都有,而大學就像是個小型社會,也是形形色色的人都有。當你試圖滿足 A 時,B 就有可能會不愉快,此時若是想要滿足 B,A 也會開始抱怨了。我想孔子的因材施教真有其必要性,可惜系上大班制的體制要實現因材施教大概可能性不高。
勉勵
分享給各位我個人最喜歡的一段話:
You can’t connect the dots looking forward; you can only connect them looking backwards.
by Steve Jobs
或許這門課看似無用,學了 Lisp 學了 Prolog 甚至是學了 Python,好像對自己根本沒什麼用處(我想 Python 不會)。但是,那可能只是近期的,未來趨勢是什麼沒有人知道,未來的際遇是什麼沒有人知道。近幾年 functional programming 又活絡了起來,會不會哪一天反而 functional language 成了主流語言也說不定,此時會寫 Lisp 反而成為一大優勢。又或許不是 functional programming 沒有熱門,反倒是 logical programming 熱門起來,那麼會寫 Prolog 就成了優勢也說不定。我個人都抱持著多學多看的態度在學習,因為多學一種,你就比別人多一個機會!共勉之。