馬麗燕 于方軍
Python是一門高級(jí)動(dòng)態(tài)編程語(yǔ)言,簡(jiǎn)潔、易讀,還帶有豐富的第三方庫(kù),能提高編程效率,很多開源的人工智能算法庫(kù)也是用Python完成的,因此很多地區(qū)的中學(xué)信息技術(shù)課本引入了Python編程教學(xué),課程內(nèi)容基本都涉及程序設(shè)計(jì)基本方法和算法思想的體驗(yàn)。以Scratch為代表的圖形化編程可以在小學(xué)入門階段學(xué)習(xí),而Python語(yǔ)言則可作為進(jìn)階編程語(yǔ)言在中學(xué)學(xué)習(xí),雖然Python未使用圖形化的編程方式,但其大量的內(nèi)置函數(shù)可以將一些具體的小任務(wù)細(xì)節(jié)封裝,進(jìn)而幫助學(xué)生把注意力集中到解決問(wèn)題的邏輯上,寫出的代碼也便于閱讀理解,從而更加符合中學(xué)生從形象思維過(guò)渡到抽象思維、數(shù)理思維的智力發(fā)展過(guò)程,有利于培養(yǎng)學(xué)生的計(jì)算思維和編程能力。
虛谷號(hào)預(yù)裝了Python,可以方便地開展Python教學(xué),同時(shí)虛谷號(hào)支持硬件,能幫助學(xué)生在真實(shí)的環(huán)境中感受程序的魅力。例如,我們可以用虛谷號(hào)的Python程序編寫一個(gè)“光控?zé)簟背绦?,讓學(xué)生感受“如果……否則……”的分支結(jié)構(gòu)。另外,虛谷號(hào)的Python編程環(huán)境預(yù)裝了占用資源比較大的jupyter notebook,因而建議用IDLE,在虛谷號(hào)上可以用“sudo apt-get install idle3”完成安裝,在網(wǎng)絡(luò)環(huán)境比較好的情況下是能夠很快完成的。
Turtle庫(kù)是Python語(yǔ)言中一個(gè)很流行的繪制圖像的函數(shù)庫(kù),運(yùn)行起來(lái)就像一個(gè)小烏龜,它在一個(gè)橫軸為x、縱軸為y的坐標(biāo)系中,根據(jù)一組函數(shù)指令的控制,從原點(diǎn)(0,0)位置開始移動(dòng),從而在它爬行的路徑上繪制了圖形,與Logo語(yǔ)言類似,非常適合設(shè)計(jì)中小學(xué)生的Python入門課例。
圖1就是用Turtle庫(kù)學(xué)習(xí)程序結(jié)構(gòu)的例子,即利用計(jì)數(shù)循環(huán)畫一個(gè)正四邊形的案例,通過(guò)這個(gè)例子可以進(jìn)行拓展,讓學(xué)生設(shè)計(jì)畫正五邊形、正六邊形……體驗(yàn)在循環(huán)語(yǔ)句中如何設(shè)計(jì)循環(huán)次數(shù)、循環(huán)條件等,這種以畫圖的形式呈現(xiàn)的直觀形象的方法,符合學(xué)生的學(xué)習(xí)習(xí)慣。
虛谷號(hào)自己有一個(gè)虛谷庫(kù)(xugu.py),支持LED燈、馬達(dá)、傳感器等硬件,這些硬件兼容Arduino環(huán)境,也就是說(shuō)Arduinon能用的硬件在虛谷號(hào)上基本都能用,如果說(shuō)基于Turtle庫(kù)的教學(xué)能讓學(xué)生“看得見”,那么基于虛谷庫(kù)的教學(xué)除了可以實(shí)現(xiàn)“看得見”,還能讓學(xué)生“感受到”。虛谷庫(kù)的使用我們可以通過(guò)下面的“點(diǎn)燈”案例來(lái)體驗(yàn):導(dǎo)入虛谷庫(kù)“import xugu”,通過(guò)led=xugu.LED(8)讓虛谷可以控制接在端口8上的LED燈,led.on()點(diǎn)亮燈,led.off()關(guān)閉燈(如圖2)。
這個(gè)案例可以讓學(xué)生體驗(yàn)無(wú)限循環(huán)編程結(jié)構(gòu),如讓學(xué)生實(shí)現(xiàn)一個(gè)“燈閃爍”的案例,就類似于Arduino中的blink案例實(shí)現(xiàn)LED燈亮一秒、滅一秒效果(如圖3)。
教材中設(shè)計(jì)的算法一般是“枚舉法”,枚舉法就是將問(wèn)題所有可能的結(jié)果一一列舉,從中篩選出正確的答案。一般學(xué)習(xí)了循環(huán)結(jié)構(gòu),就可以學(xué)習(xí)枚舉法算法,利用有限的循環(huán)嵌套列舉問(wèn)題的所有結(jié)果。這種問(wèn)題的時(shí)間復(fù)雜度為O(na),其中a可以是1、2、3或者其他常數(shù),但一定不能是變量,一旦問(wèn)題時(shí)間復(fù)雜度上升到O(nn),那么我們一般就不再叫枚舉法,而是稱為“搜索”。
計(jì)算機(jī)常用的算法大致有兩大類,一類叫蠻力算法,一類叫貪心算法,前者常使用的手段就是搜索,借助計(jì)算機(jī)的高速運(yùn)算能力對(duì)全部解的空間進(jìn)行地毯式搜索,直到找到指定解或最優(yōu)解。“搜索”一般通過(guò)遞歸來(lái)實(shí)現(xiàn),常見搜索方法有“深度優(yōu)先搜索”和“廣度優(yōu)先搜索”,但這些方法對(duì)于初學(xué)者來(lái)說(shuō)往往不是特別容易理解,下面先重點(diǎn)介紹通過(guò)循環(huán)來(lái)實(shí)現(xiàn)的枚舉法。使用枚舉法的關(guān)鍵有兩點(diǎn):一是確定枚舉范圍;二是驗(yàn)證答案的判定條件。典型的例子就是找水仙花數(shù),水仙花數(shù)是指一個(gè)三位數(shù),它的每個(gè)個(gè)位上的數(shù)字的3次冪之和等于它本身(如1^3+5^3+3^3=153)。
根據(jù)水仙花數(shù)是一個(gè)三位數(shù)可以確定枚舉范圍是range(100,1000),對(duì)于每一個(gè)三位數(shù)i可以得到百位數(shù)a=i//100,十位數(shù)b=i//10%10,個(gè)位數(shù)c=i%10,判定條件是ifi*i*i+j*j*j+k*k*k==i*100+
j*10+k,參考代碼如圖4所示。
還有一種方法是枚舉每一個(gè)數(shù)字——百位數(shù)的枚舉范圍是range(1,10),十位數(shù)的枚舉范圍是range(0,10),個(gè)位數(shù)的枚舉范圍是range(0,10),特別注意百位數(shù)是不能為0的,而十位數(shù)和個(gè)位數(shù)是可以為0的。判定條件是i*i*i+j*j*j+k*k*k==i*100+
j*10+k,參考代碼如上頁(yè)圖5所示。
其他如百錢買百雞、雞兔同籠問(wèn)題都可以用枚舉法完成,“枚舉法”是非常簡(jiǎn)單實(shí)用的算法。
另外,遞歸算法也是中學(xué)階段應(yīng)該學(xué)習(xí)的一種算法,它是指如果函數(shù)等在其定義或說(shuō)明內(nèi)部直接或間接地出現(xiàn)有其本身的引用,或者為了描述問(wèn)題的某一狀態(tài),必須用到它的上一狀態(tài),而描述上一狀態(tài),又必須用到它的再上一狀態(tài)……這種用自己定義自己的方法,稱之為遞歸。使用遞歸算法關(guān)鍵點(diǎn)有三點(diǎn):一是符合遞歸的描述,即需要解決的問(wèn)題可以化為子問(wèn)題求解,而子問(wèn)題求解的方法與原問(wèn)題相同,只是數(shù)量增大或減少;二是遞歸調(diào)用的次數(shù)有限;三是必須有遞歸結(jié)束的條件。
利用虛谷號(hào)的Turtle庫(kù)學(xué)習(xí)遞歸算法也是非常直觀的,如圖6所示是通過(guò)畫“科赫雪花”體現(xiàn)遞歸算法,幫助學(xué)生理解函數(shù)、遞歸調(diào)用等概念,進(jìn)而有效培養(yǎng)學(xué)生的計(jì)算思維。
通過(guò)枚舉法的實(shí)例我們知道,只要解決好了“定枚舉范圍”和“驗(yàn)證答案的判定條件”這兩個(gè)關(guān)鍵問(wèn)題,就可以利用“枚舉法”解決各種問(wèn)題,對(duì)于遞歸算法要確定好遞歸體、遞歸次數(shù)、遞歸結(jié)束條件。另外,算法的實(shí)例也可以結(jié)合虛谷號(hào)用硬件實(shí)現(xiàn),如可以用虛谷號(hào)做個(gè)小車走迷宮,通過(guò)枚舉方式找到所有的走迷宮可能,還可以用到其他的一些復(fù)制的機(jī)器人程序和人工智能程序中,如果學(xué)生們感興趣,可以通過(guò)社團(tuán)或競(jìng)賽作品形式,幫助學(xué)生體驗(yàn)用虛谷號(hào)編程帶來(lái)的快樂(lè)。