diff --git a/guide/learn-python-on-microbit-zh.md b/guide/learn-python-on-microbit-zh.md index 1250737..5509e01 100644 --- a/guide/learn-python-on-microbit-zh.md +++ b/guide/learn-python-on-microbit-zh.md @@ -92,7 +92,7 @@ Type "help()" for more information. 可以發現 Python 直譯器解讀了你輸入的程式,並自動算出答案。 -現在,照 REPL 提示所說的輸入 help(): +現在,照 REPL 提示所說的輸入 ```help()```: ``` >>> help() @@ -127,10 +127,10 @@ Python/micro:bit documentation is here: https://microbit-micropython.readthedocs 這是 micro:bit 的 MicroPython 內建的訊息,包含一些簡單的指引。注意到這兒也提到了 Ctrl+C 和 Ctrl+D,前者是用來中斷 micro:bit 目前執行的程式(程式執行時不會出現前面的提示),而 Ctrl+D 是用來強迫 micro:bit 重開機,以便重新測試程式。 -現在試試這個: +現在試試 ```help("modules")```: ``` ->>> help('modules') +>>> help("modules") __main__ math os ucollections audio microbit radio urandom builtins micropython speech ustruct @@ -143,7 +143,7 @@ Plus any modules on the filesystem ## Python 基礎:運算式 -在 Python 中,程式碼可分為兩類:**陳述(statement)**與**運算式(expression)**。這兩者都會執行某個功能,但運算式會傳回某個值,比如前面的 ```1 + 2``` 會得到 ```3```。 +在 Python 中,程式碼可分為兩類:**陳述(statement)**與**運算式(expression)**。這兩者都會執行某個功能,但運算式本身也代表某個值,比如前面的 ```1 + 2``` 會得到 ```3```。 運算式可以放在其他運算式中,而 Python 有很多會傳回值的東西都可以當成運算式的一部分。最簡單的運算式由值和**運算元(operator)**構成,例如上面的算式有數字 1 和 2,中間是加號運算元(+)。 @@ -181,8 +181,201 @@ Plus any modules on the filesystem 2.0 ``` +> 數字與運算元之間一定要有空格嗎?不用,甚至打一堆空格都無所謂,但留一個空格是最美觀的。 + ## Python 基礎:資料型別 +前面的運算式,其實只使用到數字而已。而在 Python 中,不同的資料有不同的**型別(type)**,而型別決定了資料(以及你對資料)能做哪些事。 + +Python 最基本的幾種型別為: + +型別 | 範例 +int (整數) | 42 +float (浮點數) | 3.14159 +str (字串) | "test" +bool (布林值) | True/False +NoneType (無值) | None + +### 整數與浮點數 + +以上面的運算元來說,整數(無小數點)和浮點數(有小數點)是可以放在一起運算的,而取決於運算元,結果會是整數或浮點數。例如,整數用 / 相除會得到浮點數, 用 // 相除卻會得到整數。 + +如果用 // 時算式裡有浮點數呢?這樣就還是會得到浮點數: + +``` +>>> 10 // 3.0 +3.0 +``` + +### 字串 + +字串前後必須用雙引號 (") 或單引號 (') 括起來: + +``` +>>> "This is a string" +'This is a string' +``` + +Python 預設是用單引號,不過大多時候沒有差別,取決於個人習慣。單引號看起來比較簡潔,但雙引號在多數語言是表示字串的通用用法。其實 Python 還有幾種其他代表字串的變形形式,不過一開始不需要知道。 + +當然,字串內容可以打任何語言。不過 micro:bit 的網頁編輯器打中文有點容易亂跳,所以還是打英文吧。 + +字串和整數、浮點數最大的差別,在於它們不能放在一起運算: + +``` +>>> 1 + 1 +2 +>>> "1" + "1" +'11' +>>> 1 + "1" +Traceback (most recent call last): + File "", line 1, in +TypeError: unsupported types for __add__: 'int', 'str' +>>> "1" + 1 +Traceback (most recent call last): + File "", line 1, in +TypeError: can't convert 'int' object to str implicitly +``` + +當你把數字寫在用 " 或 ' 括起來的字串中,那些數字就是字串而不是數字了。當你對兩個字串使用 + 號,這些字串只會直接連在一起。 + +這顯示了 + 運算元對數值和字串的意義是不一樣的,所以你嘗試執行 ```1 + "1"``` 或 ```"1" + 1``` 就產生錯誤了。之後我們會再談到怎麼藉由轉換資料型別的方式,好讓它們可以一起運算。 + +> 執行遇到問題時,Python 直譯器會顯示錯誤訊息,告訴你錯誤發生的行數(由於我們在使用 REPL 介面,所以位置是第 1 行)以及原因(TypeError,型別錯誤)。這時我們就可以根據這些訊息來嘗試排解錯誤(除錯)。 + +### 布林值 + +布林值(Boolean)就是「是/否」或「真/假」的二元結果,在 Python 中這兩個值分別是 True 和 False(第一個字一定大寫),主要用在邏輯判斷用途,這些後面會再探討。 + +Python 的布林值同時也是一種特殊的數值,0 和 None 就等於 False,除此以外的其他任何數字則等於 True。 + +### None + +None 是個特殊的值,代表沒有值的意思。你用到它的機會非常少,但有些 Python 功能會把它當成沒有值時的預設值。 + +## Python 基礎概念:變數 + +### 宣告變數 + +**變數(variable)**是用來在程式中記住資料的方法,就像是解數學方程式時的 X 或 Y。變數會有一個值,而這個值是可以隨意改變的。 + +在 Python 中,若要宣告(define)一個新變數,辦法是用 =(指派運算元)號指定或賦予一個值給某個名稱: + +``` +>>> a = 1 +``` + +此舉建立了名為 a 的變數,值為整數 1。 + +``` +>>> a +1 +>>> a + 3 +4 +``` + +如果用 = 指定新的值給 a,它的值會隨之改變: + +``` +>>> a = 2 +>>> a +2 +>>> a * 3 +6 +``` + +你甚至可以這樣寫: + +``` +>>> a = 1 +>>> a +1 +>>> a = a + 4 +>>> a +5 +``` + +請記住 = 號不是數學上的等於,而是**將其右邊的值指定給左邊**。一開始 a 的值為 1,然後我們指定新的值 a + 4(也就是 5) 給 a。因此 = 完成運算後,a 就變成 5 了。 + +最後,來按編輯器的 **Close serial** 關閉 REPL 介面,然後重開(記得按 Ctrl+C),並再次輸入 ```a``` 查詢其值: + +``` +>>> a +Traceback (most recent call last): + File "", line 1, in +NameError: name 'a' isn't defined +``` + +現在產生了錯誤,說名稱 a 不存在。這是因為重開 REPL 後,變數 a 就在記憶體裡消失了。 + +後面在執行完整的程式時,每次重新執行的效果就等同於重新啟動 REPL,所以你必須在程式裡正確的地方宣告變數,後面的程式使用它時才不會遇到問題。 + +### Python 變數是個「路牌」 + +現在要來講一個比較難懂、但仍然非常重要的觀念,因為這能解釋 Python 變數在賦值時的極大彈性。 + +在許多程式語言中,變數是個容器,實際上就是記憶體裡的一個空間,然後把值存在那裡面。既然是事先指定的空間,你只能用它來儲存特定類型的資料。 + +但 Python 的做法卻剛好相反:值本身已經存在於記憶體中某處了,你所做的其實是做一個「路牌」來指向它。 + +以 ```a = 1``` 為例,整數 1 其實已經存在於記憶體內,我們只是新增一個名稱 a 來代表它。而當你執行 ```a = 2``` 時,路牌 a 會指向記憶體中的整數 2。這時整數 1 仍然存在,只是除了直接寫出 1 以外,我們沒有別的方式能引用 1。 + +換言之,變數可以指向任何資料,就算途中改變資料的類型也無謂: + +``` +>>> a = 1 +>>> a +1 +>>> a = "test" +>>> a +'test' +``` + +上面 a 一開始是整數,後來變成字串了。 + +Python 變數能指向各式各樣的東西,這使得熟悉 Python 的人可以用變數來做一些很神奇的事。當然對初學者來說,這有時也會產生一些令人困惑的現象。 + +這裡先來舉個例子。在 Python 中,函式 **print** 能用來印出資料: + +``` +>>> print("test") +'test' +``` + +> 稍後我們會解釋什麼是函式。目前你只需要知道,函式呼叫時會在名稱後面加上 ()。 + +在 REPL 模式下,它會自動將運算式的值印出來,可是稍後在執行正式程式時就不會這樣了。反而,你得使用 print() 將訊息印在 REPL 介面內,好讓我們知道程式的執行狀況等等。 + +print 是 Python 事先定義好的東西。要是我們指定一個新的值給 print 這個名稱,會發生什麼事? + +``` +>>> print = "this is a string" +>>> print +'this is a string' +>>> print("test") +Traceback (most recent call last): + File "", line 1, in +TypeError: 'str' object isn't callable +>>> +``` + +現在 print 這個路牌指向字串 'this is a string',而不是原本能印出東西的功能了。當我們嘗試加上 () 來呼叫它時,Python 直譯器回報錯誤,說你不能把字串當成函式呼叫。(你可以藉由重開 REPL 讓 print 函式恢復正常。) + +可以想見,若你無意間使用 Python 內建的名稱,並指定新的值給它,這可能會引起一些困擾。 + +### 變數的命名規則 + +Python 變數的命名非常自由,除了不能用數字開頭以外,可以隨意混搭字母、數字和底線: + +``` +>>> _Number_01 = 42 +>>> _Number_01 +42 +``` + +Python 變數名稱也支援 Unicode,因此使用中文、日文或各國語言都是可行的。使用非 Unicode 特殊字元會產生錯誤。不過,一般習慣上還是會以英數為主,而且最好能清楚反映變數本身的用途。 + +最後就是和前面提過的一樣,最好不要使用 Python 各種內建功能的名稱,否則你會意外覆蓋掉原有的功能。若真的非用不可,可以試著在該名稱前或後加上底線,如此一來就會被 Python 視為不同的名稱了。