牟曉東
高中信息技術會考對Python語言的基本語法應用及程序代碼的補充解析提出了一定要求,除了通過選擇題對變量名命名規則、表達式運算結果的求解等基本知識點進行考查外,還有通過閱讀程序段來寫出運行結果的方式,或是根據題意進行程序代碼的補充填寫的方式。在Python的學習備考過程中,如果能夠結合樹莓派開源硬件編程,將程序的運行結果進行“圖解”——以一種更為直觀的方式來“看”程序,無疑會極大提高學生學習編程的興趣。在此以“‘只有一人說謊’的抓小偷”邏輯判斷和簡易“十進制轉二進制”兩道Python會考題為例:
有四個嫌疑人甲乙丙丁涉嫌偷盜,可以肯定的是其中一人就是小偷。在警察審訊過程中,甲說:“不是我!”乙說:“是丙干的!”丙說:“是丁干的!”丁說:“丙在冤枉我!”如果他們四人當中只有一人說了假話,請編程判斷誰是小偷。
在進行Python代碼運行的單純文字結果輸出基礎上,將樹莓派安裝上四支不同顏色的LED燈分別代表甲乙丙丁四個嫌疑人進行“圖解”,最終實現程序精準控制某LED燈亮起,對應此嫌疑人為真正的小偷。
首先,將古德微擴展板正確安裝于樹莓派上;接著,將紅色、綠色、黃色和藍色四支LED燈均按照“長腿正、短腿負”的原則,分別插接至擴展板的5號、6號、12號和16號插孔(對應甲乙丙丁四個嫌疑人);最后,插接上電源線為樹莓派供電啟動系統(如圖1)。

通過Windows的“遠程桌面連接”輸入樹莓派的IP地址,進入后點擊“編程”—“ThonnyPythonIDE”菜單開始代碼編程。
首先,通過“from gpiozero import LEDBoard”語句,實現從GPIOZero庫中導入LEDBoard類;接著,使用“LEDs = LEDBoard(5,6,12,16)”語句來組建四支LED燈的“燈陣”,其中的參數“5,6,12,16”即對應各LED燈所插入樹莓派的引腳號;然后,建立嫌疑人變量列表:“persons = [‘甲’,‘乙’,‘丙’,‘丁’]”,注意其中數據的次序是與紅色、綠色、黃色和藍色LED燈一一嚴格對應的;再建立一個for循環結構對persons列表所存儲的四個數據進行“遍歷”,變量flag的值為一個邏輯值的運算表達式:“flag = (thief!=‘甲’) + (thief==‘丙’) + (thief==‘丁’) + (thief!=‘丁’)”——Python運算時會將邏輯真(True)的值設為1、將邏輯假(False)的值設為0,該行代碼是根據題意分別將甲乙丙丁四個嫌疑人的“口供”進行了Python化“轉譯”;如果四個邏輯值相加的結果是3的話(三個人說的是真話),則先打印輸出真正的小偷:“print(‘嫌疑犯是:’,thief)”,再將該嫌疑人所對應的LED燈“點亮”:“LEDs.on(persons.index(thief))”,其中的“index(thief)”是作為變量persons列表數據引用索引序號(如圖2)。

將程序代碼保存為Catch_Thief.py文件,點擊“Run”按鈕運行程序進行檢測,下方的程序輸出結果顯示為:“嫌疑犯是:丙”,同時樹莓派上的第三支黃色LED燈也會亮起(如圖3)。此時,程序中的變量flag的值為3(if條件成立),變量thief的值是“丙”,而“persons.index(thief)”的值為索引號2,它作為LEDs.on的參數時就會對應亮起樹莓派12號引腳上的第三支黃色LED燈。

對于會考中經常涉及的較小數字進制轉換問題,比如16以內的十進制數(相當于一個十六進制位)轉二進制數,完全不必使用“除以2倒序余”法,可以直接嘗試“8421”分解組合求和法,使用不同位的“權數”進行兩種進制間的快速任意相互轉換。比如:給出一個十進制數6,通過“8421”直接分解為“4+2”,對應寫出二進制結果是“110”;如果是十進制數9,則分解為“8+1”,對應的二進制數就是“1001”。如果待轉換的十進制數大于15,則在“8421”的基礎上依次向左擴充一位“16”,再不夠就再擴充第二位“32”……
保持上一道題的樹莓派及四支LED燈等實驗器材和連接方式不變,設定“8421”的對應數位分別是從高位到低位的紅色、綠色、黃色和藍色LED燈,相當于四個二進制位,最大可“圖解”表示的十進制數為15(對應十六進制的F)。對于程序將用戶從鍵盤上接收到的十進制數,轉換為四位的二進制數后,將對應數位是1的LED燈“點亮”,而數位為0的則保持熄滅狀態。
在PythonIDE中仍然先使用“from gpiozero import LEDBoard”語句,從GPIOZero庫中導入LEDBoard類,同樣是再組建LED“燈陣”:“LEDs = LEDBoard(5,6,12,16)”;接著,通過input()和int()函數為變量My_Decimal賦值,實現接收用戶從鍵盤上輸入的任意一個16以內的十進制整數:“My_Decimal = int(input(“請輸入一個16以內的十進制整數:”))”;語句“My_Binary = format(My_Decimal,‘b’)”的作用是為變量My_Binary賦值,該值是通過format將變量My_Decimal的值轉換為對應的二進制“數”——特別要注意這是一個字符串類型的數據;考慮到用戶輸入的十進制數如果是“大于等于0且小于等于7”時,轉換出的二進制字符串數據是不足四位的(1位、2位或3位),此時無法與樹莓派的四支LED燈陣一一對應,因此必須要對二進制字符串數據進行高位“補零”操作——建立變量My_Binary_4,為其賦值為“My_Binary.rjust(4,‘0’)”,即通過rjust右對齊來實現四位數據的構建。
接下來,建立一個for循環,通過range(4)實現從第1至第3的四次循環,依次判斷變量My_Binary_4中所存儲的四位字符串型二進制數是否有1:“if My_Binary_4[i]==‘1’:”;條件成立的話,則控制對應編號的LED燈發光:“LEDs.on(i)”;最后,將用戶輸入的十進制整數和轉換后的二進制數通過print進行輸出:“print(‘十進制整數’,My_Decimal,‘轉換為二進制數是:’,My_Binary)”(如圖4)。

將程序保存為Decimal2Binary.py文件,點擊“Run”按鈕運行進行兩次測試:第一次在“請輸入一個16以內的十進制整數:”提示后輸入6,回車后發現樹莓派上的中間綠色和黃色LED亮起,同時程序下方也有“十進制整數6轉換為二進制數是:110”的提示輸出;第二次測試數字9,回車后會亮起兩側的紅色和藍色LED燈,同時提示信息會顯示為“十進制整數9轉換為二進制數是:1001”(如圖5),實現了簡易“十進制轉二進制”的圖解過程。

程序本身只是簡單地實現了將一個0至15的十進制整數轉換為二進制數輸出及對應的LED燈發光或是熄滅的圖解功能,既沒有對用戶從鍵盤上輸入的數據進行一定的“容錯”判斷處理(比如輸入了小數或是超過15的整數),也沒有加入循環控制用戶的多次測試(程序運行一次只能測試一個數據),均可以考慮進行程序的進一步完善。同時,也可以嘗試另一種相似的圖解方式,比如使用for循環(range(16)),依次將0~15這十六個十進制整數均轉換為對應的二進制數,每隔一段時間(比如3秒鐘)就輸出一組數據,同時也會控制樹莓派上的LED“燈陣”進行對應的亮燈、關燈顯示,實現四個二進制數位從“全滅”(0000)到“全亮”(1111)進制數據轉換的動態演示,大家不妨一試。