董燁華
(浙江省紹興市第一中學,浙江 紹興 312000)
計算思維是個體運用計算機科學領域的思想方法和在形成問題解決方案的過程中產生的一系列思維活動。[1]計算思維的本質是抽象。[2]編程教學是計算思維培養的重要手段。目前,面向小學生的編程課程,以Scratch一類的可視化編程和樂高機器人一類的實體設備編程為主。像C++這類注重算法學習的編程課程是比較小眾的,究其原因在于C++編程解決的問題較抽象、思維難度較大。筆者面向小學高年級學生開設C++編程課程,培養學生計算思維,嘗試將編程解決的問題與小學數學課堂典型問題結合,使得教學更“平易近人”。
瑞士知名教育學家、心理學家皮亞杰提出了兒童認知發展理論。根據該理論,小學高年級兒童認知發展正處于具體運算階段向形式運算階段過渡,已經適合抽象思維的培養。抽象是計算思維的核心。在小學高年級通過編程培養學生計算思維,正是抓住了學生抽象思維發展的關鍵時期。在教學中,要提升并借助學生的形象思維能力,培養學生的抽象思維能力,最終使學生在問題解決過程中能習慣運用計算思維。
小學高年級學生已經具備了良好的語言學習基礎。語言語法的突出特點是其抽象性。除了語音和詞匯均各有其抽象性,語法的抽象性是所有這些抽象基礎上的更高層次的抽象[3]。面向小學生的C++編程教學,一方面,要以問題解決為中心,弱化語句語法學習,減少學生因為語法的抽象對問題解決感到困擾,語法學習做到夠用就行。例如,C++的循環結構有for循環、while循環、do…while循環,在實際教學中可以先只學一種for循環,直到學生能熟練運用,再拓展介紹其他循環語法。再例如,for循環在實際編程中可以有很多靈活變化的寫法,教學時要盡量從最一般的格式入手,在之后學習中根據問題需要再做格式上的加減操作。另一方面,要利用好學生原有自然語言抽象概念、數學語言抽象概念,將其遷移到編程學習中,幫助學生完成二次抽象,即計算思維相關的抽象。可以讓學生將C++語法保留字作為英語單詞記憶,記住了單詞的含義也就大致理解該保留字的C++語法意義。然后,要求學生習慣用自然語言將問題解決的算法思路講出來。實踐表明,通過以上問題解決中自然語言和C++代碼的抽象含義對應,學生很快理解了if語句語法,掌握速度和理解Scratch編程相應功能模塊無明顯差異,后者是自然語言和Scratch圖標抽象含義的對應。
計算思維源于數學思維與工程思維,數學思維最大的認知特征便是:概念化,抽象化,模式化。《普通高中數學課程標準》提煉的數學學科核心素養為:數學抽象、邏輯推理、數學建模、直觀想象、數學運算、數據分析,而這些正與計算思維過程中分析數據、界定問題、分解問題、抽象特征、建立結構模型、算法實現等環節高度對應。所以,從數學問題出發在編程學習中提升計算思維能力,具備良好的遷移基礎,可以實現數學學科核心素養和信息技術學科核心素養雙發展。
分析、界定與分解是在收集、分析數據基礎上實現數據表征、概念界定、明確問題實質,并將一個復雜的問題分解成若干易處理的子問題的過程。教學中可以從典型數學問題出發,將問題解決過程中分析、界定與分解的思維過程進行強化。例如,人教版《數學》三年級下冊的一個面積計算問題(以下簡稱例1):客廳的長是6米,寬是3米;正方形地磚的邊長是3分米;問鋪滿客廳地面一共要用多少塊地磚。經過分析,我們可以得出問題涉及:正方形、長方形、邊長、長、寬、面積等概念,問題的實質是與面積有關,涉及不同長度單位的換算,是整數運算。問題可以分解為:①求客廳地面面積問題;②求地磚面積問題;③求兩個面積之間的關系問題。還可以分解為:①求客廳地面的長對應幾塊地磚的問題;②求客廳地面的寬對應幾塊地磚的問題;③已知客廳地面長和寬分別對應地磚數,求總地磚數問題。
抽象是從眾多的事物中抽取出共同的、本質性的特征,而舍棄其非本質的特征的過程。計算思維下的抽象可以歸納為三個逐級上升的層次:概念抽象→數學抽象→計算抽象。[4]建模就是建立結構模型,是為了理解事物而對事物做出的一種抽象,同樣可以對應概念建模、數學建模、計算建模三個層次。回到例1,之前的教學中學生應該已經理解了正方形、長方形、長、寬、面積等抽象概念,在本問題中是把地磚抽象為邊長為3分米正方形這個數學模型,地面抽象為長6米、寬3米的長方形模型。如果采用例1中第二種問題分解方式,還需要分別從地面和地磚邊長中抽象出線段模型。
計算建模是要讓這個模型可以被運算,可以交給計算機幫助運算解決,要考慮從具體個例到一般情況的抽象泛化。例1中提供的數據符合長方形的長和寬是正方形邊長的倍數,針對這組特殊數據,可以在整數運算范圍下,采用前面提到的兩種方式來分解問題、抽象建模。如果把問題數據一般化,可能出現客廳地面面積不能被瓷磚面積整除的情況,建模就要考慮小數運算,還要從工程思維的角度分析,不湊整的面積地磚怎么拼,1/3塊地磚算不算用掉一塊。于是在計算建模的時候,需要加上一些約束條件。如果條件保證客廳地面面積數據一定能被瓷磚面積數據整除,又會出現前面第一種問題分解方式在某些數據情況下不符合實際的情況,比如長6米、寬1米的客廳地面和3分米邊長的地磚,雖然兩者面積可以整除,但實際鋪設的時候地磚是要切割了的。所以,圍繞典型數學問題,教師需要在教學中幫助學生鞏固相關概念,明確數學模型;要引導學生提煉出可運算、一般化的計算模型。
算法的概念源自數學,在數學中,算法通常是指能夠使用計算機來解決的某一類問題的步驟或程序,這些步驟或程序必須是明確和有效的,而且能夠在有限步驟之內完成。[5]浙教版《信息技術必修一數據與計算》教材中給出廣義的概念,“算法”是解決問題或者完成任務的一系列步驟,解決的問題不僅僅指傳統意義上的計算任務(算術),還可以是社會生活中各種事務的處理。在計算機學科領域內,“算法”指的是用計算機解決問題的步驟,是為了解決問題而需要讓計算機有序執行的、無歧義的、有限步驟的集合,需要解決的問題包含數值計算和非數值計算的數據處理。根據廣義的算法概念,可以認為計算思維不僅適用于數學學科和計算機學科,也適用于其它各個學科領域的問題解決過程,是一種通用思維。數學學科和計算機學科中“算法”的定義高度一致,可見,從解決數學問題出發培養學生計算思維是一條最直接的路徑。例1面積計算問題,在計算建模基礎上,分解的子問題①、②、③,可以設計成有先后關系、依次執行的三個算法步驟:①→②→③或者②→①→③,每個子問題又有相應的算術運算步驟。
在C++語言入門教材里一般都會用到一些小學數學相關的例題和練習題,對于大部分教材用戶,小學數學問題已經不存在數學建模的困難,所以這些題目的作用主要是幫助熟悉C++語法,但在面向小學生的教學中,這些題目往往是開展計算思維培養的好素材。教師要善于把數學問題和小學數學課堂結合起來,為最終通過計算機編程解決搭建良好的思維情境。例如,判斷閏年問題是編程常用例題,教師可以從人教版《數學三年級下冊》第六課“年、月、日”找到數學基礎。教學中可以結合數學教材,完成閏年等概念抽象,同時明確什么是判斷閏年問題。接著,通過分析閏年形成的原因,讓學生了解數學教材里判斷閏年的規則“公歷年份是4的倍數的,一般都是閏年;但公歷年份是整百數的,必須是400的倍數才是閏年”。下一步,把年份抽象成一個數字,問題就轉換為對年份數字的判斷,完成計算建模。將閏年判斷規則整理為可操作的算法步驟:判斷年份數字能被4整除但不能被100整除,或者判斷能被400整除。最后,用C++代碼實現,語法要求并不高,套用IF語句格式就行。另外,像“雞兔同籠”問題也是很好的例題,人教版數學教材里先讓學生通過列表分析“雞、兔、腳”之間的關系,所以編程教學中需要從枚舉算法入手,之后可以拓展解析算法,這樣會更符合計算思維解決問題的過程。
教師可以從數學教材中找適合運用計算思維的問題實例。例如,人教版《數學五年級上冊》第七節“植樹問題”。植樹問題是指在一定的線路上,根據總路程、間隔長和棵數進行植樹的問題。編程解決的問題簡單描述為“總路程為L米的馬路,在一邊每間隔S米種M棵樹,一共要種幾棵樹”。抽象建模:樹用點來表示,植樹的沿線用線來表示,這樣就把植樹問題轉化為一條非封閉或封閉的線上的點與被均分的線段之間的關系問題。算法設計:根據問題描述,如果線段兩端都植樹,計算公式:總數=(L÷S+1)×M。代碼編寫只要定義相應int類型變量,順序結構可以實現。
可以對教材中的數學問題進行拓展。例如,植樹問題進行拓展,描述為“長度為L米的馬路上有一排樹,樹從頭到尾間隔1米種植,現在馬路中的一段要建十字路口,要把從A米起到B米之間的樹移走,問還有多少棵樹”。抽象建模仍然是線上的點與被均分的線段之間的關系問題。算法可以0到A-1的線段上點的個數加上B+1到L的線段上點的個數,也可以是0到L的線段上點的個數減去A到B的線段上點的個數。
將上述植樹問題再進一步拓展,就是一道經典的全國信息學奧林匹克聯賽試題“校門外的樹”(NOIP2005普及組第二題),問題簡單描述:某校大門外長度為L米的馬路上每間隔1米種著一棵樹,把馬路看成一個數軸,即數軸0到L的位置都種有一棵樹,馬路上有一些區域要用來建地鐵,這些區域用它們在數軸上的起始點和終止點的坐標表示,這些坐標都是整數,區域之間可能有重合的部分,現在要把這些區域中的樹移走,問馬路上還剩多少棵樹。問題拓展到這里,學生對其數學模型已經很清楚了,但在計算的時候如果分別考慮地鐵區域的起始點和終止點坐標,一段一段來計算會十分復雜。計算建模可以考慮按建地鐵區域要求將所有樹都移走后數軸的最終狀態,0到L的數軸上一些點有樹一些點沒有。所以,C++編程中定義長度為L的數組,模擬這個數軸狀態變化就行。
C++語言在小學被認為是編程界面枯燥、學習難度大的一種編程語言。筆者認為,字符化編程界面并不是孩子們缺少興趣的原因,看煩了都市五顏六色的霓虹,你會發覺寂靜夜空的美麗。編程學習中的抽象和算法設計的復雜,才是真正讓孩子們感到困難的,而這些正是計算思維培養的最核心內容。對于小學高年級的孩子來說,在編程學習中過多地將時間花費在如Scratch圖形對象的設計上或者機器人編程硬件設備的組裝上,而問題本身的算法難度不提升,那么,一則培養效率低下,二則會阻礙孩子抽象能力的發展。從小學數學問題出發在小學高年級開展編程教學是計算思維培養一條順理成章之路。