是時候改變自學(xué)編程方法了,這篇國外網(wǎng)友的教程被fast.ai創(chuàng)始人點贊
本文經(jīng)AI新媒體量子位(公眾號ID:QbitAI)授權(quán)轉(zhuǎn)載,轉(zhuǎn)載請聯(lián)系出處。
還記得你大學(xué)時的Java、C、Python等語言是怎么學(xué)習的嗎?讓我們打開經(jīng)典教材和網(wǎng)絡(luò)課程看一下,幾乎都是下面的套路:
學(xué)習變量、數(shù)組、對象等專業(yè)詞匯;
查看編程示例,依葫蘆畫瓢寫代碼;
重復(fù)以上步驟,直到學(xué)完全部課程。
然而一位程序員Jeff Olsen卻認為,這種教學(xué)方式太過時了。
編程和計算機科學(xué)的關(guān)系,就如同烹飪和化學(xué)的關(guān)系一樣。即使沒搞清楚化學(xué)變化,一樣可以做出美味的煎蛋。
為此,他提出了一套編程教學(xué)的新思路,Jeff的想法在Haker News上獲得了廣大程序員的贊同。
甚至連課程平臺fast.ai的創(chuàng)始人Jeremy Howard也來捧場:“這與我們平臺上深度學(xué)習的教學(xué)方法相似。”
有網(wǎng)友指出,對于初學(xué)者而已,歸納推理能力的形成非常重要,
這種方法不僅對老師有意義,對于自學(xué)編程的人來說也不失為一種更好的學(xué)習方法。
改變教學(xué)方法
Jeff提出的教學(xué)方法叫做“預(yù)測至上”。先給學(xué)生一段簡單的代碼,讓他們預(yù)測會發(fā)生什么,然后從運行結(jié)果中學(xué)習語言的一些特性。
為此,Jeff提出了編程教學(xué)的5條標準,符合這些標準的教學(xué)課程才能將知識點傳達到位:
- 還不知道此語法的學(xué)生,能找出這段代碼的作用嗎?
- 這段代碼是否與以后可能遇到的代碼合理的相似?
- 命名的文字是否有意義,變量是否命名正確?
- 問題是否允許學(xué)生專注于代碼中最重要的部分?
- 代碼示例是否需要某些先驗知識,還是能讓所有人都能理解?
具體來說,就是不直接提概念,而是先提出一個難題供學(xué)生解決。
這個難題包含了當天的知識要點,然后要求學(xué)生根據(jù)這個難題創(chuàng)造一些新的代碼,在解決問題的過程中學(xué)習專業(yè)術(shù)語。
這不僅是一份給教師的指南,我們在學(xué)習編程時,最好也帶著問題去思考、學(xué)習代碼,而不是機械地去重復(fù)書中的示例,這樣才能真正掌握技能。
幾個例子
Jeff首先展示了編程最基本的Hello World程序,他的方法與傳統(tǒng)方法略有不同。我們先看這段代碼:
- name = "Tamara"
- print("Hello" + name)
運行以上程序會發(fā)生什么?
一般,我們憑借直覺能猜到運行結(jié)果中會出現(xiàn)Tamara,而實際的運行結(jié)果是HelloTamara,中間沒有空格。
接下來如何讓程序輸出帶空格的結(jié)果,必然要進行一輪調(diào)試。
在這個過程中,Jeff沒有說過字符串、變量等概念,但是在解決這個問題的過程中,我們已經(jīng)掌握了print函數(shù)、字符串的拼接等一系列用法。
Jeff還舉了幾個例子,希望能糾正傳統(tǒng)教學(xué)課程里死板的內(nèi)容。
1、條件判斷
傳統(tǒng)教學(xué):
- if 1 > 2:
- print("1大于2")
- else:
- print("1不大于2")
在這個例子中,學(xué)生只能查看代碼,而不能通過使用代碼學(xué)會條件判斷。
Jeff建議把代碼改成:
- age = 15
- if age >= 18:
- print("你可以購買R級電影票")
- else:
- print(f"再過{18 - age}年你才滿18歲")
終端中將輸出什么內(nèi)容?你的回答應(yīng)該是:再過3年你才滿18歲。
接著,Jeff丟出了幾個問題:
整段代碼里都沒有3,你怎么知道會出現(xiàn)“ 3年”?我們?nèi)绾胃某绦騺盹@示其他語句呢?縮進對我們的程序有什么作用。
通過這3問,學(xué)生知道了if-else語句的縮進格式,還知道如何用通過更改條件來實現(xiàn)其他的判斷。
2、數(shù)組
傳統(tǒng)教學(xué):
- a = [3, 2, 7, 5, 3, 9]
- print(a[2])
- # returns 7
在這個示例中,為何a[2]的結(jié)果是7,沒學(xué)過編程的人可能無法理解,甚至會產(chǎn)生錯誤的理解:哦,原來是輸出第2個數(shù)字后面的一個數(shù)字。
Jeff建議改成:
- favorite_foods = ["壽司", "玉米粽子", "披薩", "烤雞肉"]
- print(favorite_foods[2])
這段程序的輸出結(jié)果會是什么?我們?nèi)绾未蛴〕龅谝环N食物、最后一種食物?如果把最后一句改成favorite_foods[10]會發(fā)生什么?
通過這個簡單的示例,學(xué)生可以了解數(shù)組、索引已經(jīng)索引超出范圍的錯誤。
3、對象
傳統(tǒng)教學(xué)
- Class Dog:
- def __init__(self):
- pass
- def speak(self):
- print("woof!)
- Fido = Dog()
- Fido.speak()
這段代碼雖然用小狗做例子,看似生動有趣,其實存在著一些問題:
(1)狗并不存在于網(wǎng)絡(luò)空間中。
(2)使用9行代碼來創(chuàng)建和調(diào)用函數(shù),實際可以更短。
(3)這種方法創(chuàng)建的所有狗都只有相同的功能,那為何還要創(chuàng)建一個類呢?
Jeff建議改成:
- user1 = User("Ty", "Tdog@aol.com", 16, "Pa$$word")
- user2 = User("Sarai", "SMendes@hotmail.com", 15, "Kangaroo!")
- user3 = User("Osu", "Osu22@gmail.com", 12, "12345abcde")
- print(user2.age)
提問環(huán)節(jié):第一個用戶的電子郵件是什么?哪個用戶的密碼最弱?最后一行將輸出什么?
學(xué)生通過這種方式先學(xué)習了創(chuàng)建對象的方法,至于代碼中出現(xiàn)的User(),接下來就可以很自然地教他們?nèi)绾蝿?chuàng)建類了。
最后附上Jeff博客的鏈接,希望他的方法對你學(xué)習編程有所幫助。






