那另外就是說呢這個事實上呢在這個 Python 裏面的函數,傳回值可以不止一個, 可以不止一個,事實上可以傳回很多個,你可以傳回兩個,三個,四個 五個,都是可以的。 那所以我們這邊給一個例子就是說呢, 假設我們現在寫了一個函數,那這個函數做什麼事情呢, 那就是說呢,傳回,就是它的輸入是四個變數, 四個變數,那我們把它叫做 x1,x2,x3 跟 x4, 然後呢它會計算這四個變數裏面的最大值跟最小值,同時 把最大值跟最小值都傳回去,所以它這邊呢做什麼事情呢?我們就 定義一個函數叫做 min_max,那 min_max 它的傳入值總共有四個,總共有四個, 然後呢,然後你用,我們就用這個 minimum 跟 maximum 去計算 x1,x2,x3,x4 的最大值跟最小值, 然後傳回它的,先傳回最小值,再傳回最大值, 然後中間,r1 跟 r2 用一個逗點把它分開來,用逗點把它分開來, 那所以這個, 所以它就同時可以傳回兩個數字嘛,那你要怎麼接它呢?我們先 往下看一下你怎麼接它,我們接它的時候是,一樣,就是說呢用兩個變數去接它, 在這邊我們用 out1,out2 等於某個函數,對不對? 意思就是說呢我們就是去執行這個函數,傳進去 a1,a2,a3,a4, 然後呢傳回值,然後 out1 跟 out2,把它接起來, 所以這時候呢,out1 就會接到 r1,out2 就會接到 r2,大概是這個樣子。 那另外就是說這個 a1,a2,a3,a4 怎麼來的呢? 我們就用 input 這個,這一個函數,這個是一個內建的一個函數 那它的功能就是可以 take 這個使用者從這個鍵盤上面的這個輸入的這個資訊, 所以呢這個你如果寫 input,然後呢 這個括號,引號,Provide input value a1, 然後這時候呢這個程序就停在那裏,等你打 a1 這個數字, 按 enter 之後呢,它就會進入下一行,然後呢我們就叫他再輸入第二個數字叫做 a2, 再來是 a3,再來是 a4,然後呢我們就把 這四個 a1,a2,a3,a4,把它丟到 min_max 函數裏面,所以呢呼叫 min_max 之後呢,它就會去計算 這四個數字的最小值跟最大值,然後傳回去,所以它是同時把最小值跟最大值一起傳回去, 然後最後我們就可以把這個,這個你接到的這個最小值跟最大值 把它印出來。 那 所以呢我們來看一下一個這個 這個執行的狀況,所以假設我們現在呢就是執行這個 執行這個我們剛剛寫的那個程式,所以這個 9 是你打的,所以就是 它會,程式會說 Provide input value a1,然後呢 就打 9,按 enter 之後,它就會說 Provide input value a2, 再打 5,按 enter,再打 2,按 enter,再打 7,按 enter,所以就輸入了 9,5,2,7 這四個變數的值,對不對? 然後呢,然後你就,然後我們就呼叫這個 min_max 那個函數,所以它就 會把最小值跟最大值傳回來,我們再把它印出來嘛,對不對? 所以我們就印到了這個,最小值是 2,最大值是 9,恩,OK? 那所以呢,那我們再試點別的吧,好,那我們來看 就是說我們現在假設這個再試另外一組數字,我們說 a1 是 55, a2 是 2,a3 是 9,a4 是 1111,對不對? 哇,這時候怪怪的,爲什麼它的 minimal value 是 1111? 最大值卻是 9 呢?很奇怪,很奇怪,對不對? 發生什麼事?發生什麼事?那各位現在我們遇到了什麼?我們遇到了一個 bug, 遇到了一個 bug,那遇到 bug 怎麼辦? 遇到 bug 千萬不要驚慌,因爲呢 也許這是你第一次遇到 bug,但是呢,這不會是你最後一次遇到 bug,你的人生 就是會不斷地 debug,那所以呢,千萬不要驚慌,千萬不要驚慌,然後我們就是 有 bug 我們就把它處理掉,把它處理掉,處理掉之後 人生就變得更美好,對不對?就可以往下走,那 所以我們來看看,所以我們要,我們要看看,我們要想辦法知道說這到底是什麼問題, 那在想要知道這是什麼問題之前,大概我們都會先猜測一下,都會先猜測一下,那你也可以就是 把這個 video 停下來,你自己先想一下可能是什麼問題,可能是什麼問題, 那不過有時候光這樣想,有時候想不出個什麼東西,所以我們還是要做點 事情,debug 並不是光用空想, 那所以我們通常怎麼 debug 呢?我們通常會讓這個 python 進入一個這個互動的模式, 來做 debugging,那也許你現在這個執行 python 的程式你是直接讓它從頭執行到尾之後這個程式就結束了,python 的這個程式就結束了, 那我們在 debugging 的時候我們會希望說呢,這個 python 在執行完你的程式之後呢,它是沒有結束,它會停在那裏, 然後呢讓你去跟它互動,就是它是一個存在一個互動模式,那這個互動 模式怎麼做呢?這個互動模式的這個設定呢其實也很簡單,就是說呢 你就是,如果你是,你的 python 叫做 python3, 有些人的安裝的時候是叫 python,有些人叫 python3,whatever 叫什麼,就是說呢 當然就是說我們規定就是第三版的,我們現在就是針對第三版來做,那有些人 是第三版是叫 python3,有些人是直接叫 python,那 whatever 你叫什麼呢,如果是 後面接上 -u,-i,然後你的 python 的 script 之後呢, 那這時候你執行的時候呢,你就會是執行完之後它就會留在 python 的 shell 裏面,所以你就可以繼續打字,可以跟它互動, 所以我們如果做這個事情的話呢,我們再重復一下剛剛的 剛剛發生的這個狀況,就是說呢我們去把這個 去把這個 55 啊,2 啊, 9 啊,1111,把它這個印出來,把它這個 把它再執行一次,就會發現說一樣,minimum 跟 maximum 是不對的, 那所以我們現在,當然就是說,就是 debugging 就是我們要從頭來看,到底發生什麼事情,對不對?到底發生什麼事情, 所以我們的輸入是 a1,a2,a3,a4,對不對? 那我們何不把 a1,a2,a3,a4 的值印出來看看?好,所以這個時候呢 我們就要來印 a1,然後就發現說這個 a1 的數字怎麼會是 引號的 55 啊,引號 55 是什麼意思? 引號 55 的意思是說,它不是一個整數,或者是一個浮點數,它事實上是一個字串, a2 的狀況也是一樣,它是一個引號 2,所以它事實上它也不是一個 數字,而是一個字串,雖然說你看起來說,看起來它是 2,但是它是一個字串 2,而不是數字 2, 對不對?a3 跟 a4 的狀況也是一樣, 好,a4 沒有印出來,不過 whatever,就是類似的狀況, 而且你如果問它說,你說 a1 的 type 是什麼呢?它會告訴你說它是一個 str,它是一個字串,那其他也是一樣,都是這個 字串,那字串這樣子就合理了,對不對?爲什麼這樣子合理呢? 因爲呢,字串比大小的方式跟數字 integer 或者 float 浮點數 比大小的方式是不一樣的,字串比大小 的方式一般來說是從第一個字元開始比, 比完之後再比第二個字元,再比第三個字元, 所以呢,而且呢它比的大小是它的內部的編碼的大小, 而不是你看到的那個數字的大小, 所以在這邊呢,如果我們去比這個 55,2, 9,1111 這四個字串的大小,怎麼比呢? 它的比法呢就會是先把第一個 character 拿來,它是 5,2,9,1,然後呢去比 5,2,9,1 內部的編碼誰比較前面,誰比較後面, 那這個剛好就是說呢,這個電腦內部的編碼 1 到 9 的編碼,剛好是 1 是比較小,9 是比較大,而且剛好是一個連續的, 所以呢這個比較的結果就會是 1 是最小的, 1 是最小的,所以這樣子就很容易可以理解說爲什麼呢,它會把 1111 放到最小值,把 9 放到最大值, 因爲就是說呢,字串的大小的確是這個樣子, 是 1111 是最小,因爲它是 1 開頭的,1 開頭的, 那 1 的這個內部的編碼是這四個裏面最小的,那 但是這不是我們要的啊,這不是我們要的,我們要的是什麼? 你要的是一個這個把它當成是一個這個浮點數的數字的這種 比較,對不對?所以我們必須要做一個處理,我們必須要做什麼處理呢?我們必須要把 這個字串呢,把它轉成浮點數,這樣子它才會對。 因為在這邊字串大小的比較,是一個沒有意義的比較。 所以要怎麼做呢?就是把它轉換成所謂的這個 浮點數,轉換成浮點數。 那這個做法事實上也非常的單純,好。 那整個程式呢,事實上都跟原來的好像沒什麼差別,唯一的差別、 就是說這邊全部都是一樣的。 那唯一的差別是什麼呢?就是說我們加了這一行,我們在這個 a1 a2 a3 a4 在傳進 min_max 之前呢,我們用這個 float 這個函數呢把它包起來,那這個會做什麼事情呢? float 這個函數它會 take input 然後把它轉成 這個浮點的輸出,然後呢,這個才會 才會丟給這個 min_max,所以它四個這個傳入值都做這個事情。 這時候呢,結果應該就會對了吧?好,那我們來試試看。 對不對? 有對嘛?好,那我們就同樣用剛剛的那個例子,55 啊、 2 啊 好,9 跟 1111,這時候就對了。 minimal 是 2 而 maximal 是 1111,對不對?這樣就沒錯。 而且它,你看到它這邊有一個 .0 因為我們已經把它轉成了 這個浮點數了。 那我們如果再測試一個,比如說有負數的狀況會怎樣呢?有負數的狀況也是 行為也是很正常,對不對。 最小值是 -3,最大值是 99.4,對不對?好。 所以呢,這就是一個 各位剛剛看到的就是是一個這個典型的所謂 debugging 的過程,debugging 就是 是你一定會做的事情,各位以後在寫作業,或者你之前寫的這些作業 一定有遇到類似的狀況,那就是千萬不要驚慌。 好,這是 人生正常的一個部分,好。 那 這個所以另外一件事就是 如果這個函數裡面沒有 return 這個 keyword 會怎樣呢?好。 那 Python 依然它會執行,只是它在執行 到最後一行,這個函數定義的最後一行,執行完之後 呢,然後呢,它就一樣會傳回一個值,那這個值,你如果沒有 return 這個 keyword 的話呢,或者你有 return 這個 keyword 但是後面沒有接 變數的話呢,那它就會傳回一個所謂的 none 這個東西。 那 none 這個東西呢是一個特殊的一個物件。 那這個特殊的物件呢,就是基本上就是說沒有東西的意思。 然後呢,這個事情呢常常也會是造成各式各樣問題 的一個原因,就是說呢,很多時候,如果你寫的這個函數,本身應該是要傳回值的, 但是呢,你最後卻沒有傳一個東西回去的話,那 Python 就會自己 幫你傳一個 none,那這個東西就會造成你後續的一些 這個執行上面的問題,所以我們來看一個簡單的例子。 那很多時候呢 像剛剛那個問題是無心的啦,有些人是有意,有些人是無心,那 很多時候 bug 都是無心的,那無心的 bug 還是 bug,還是要處理,對不對。 所以我們來看這個例子。 那這個例子做什麼事情呢?這個例子是幫你去算所謂的 這個絕對值,我們把它取一個名字,比如說 myabs。 就是 my absolute value 的意思。 那它就是take一個傳入值 x,我們假設它是一個 這個浮點數,或者是一個整數啦,然後呢,如果 x 是小於 0 的話呢,我們就 return -x。 對不對?如果 x 大於 0 的話,我們就return 一個 x,對不對。 這是一個簡單的做絕對值的方法。 所以呢,各位,如果說呢,我們定義完這個 函數之後,你先想想看,先不要急著把它打進這個 Python 裡面。 如果說呢,我們來看看我們傳 -3.5 會怎樣? 那我們如果傳 -3.5 的話,x 就是 -3.5 啊,那 x 有小於 0 嘛?有。 所以它就會傳回 -x,所以它就會變成 3.5。 對不對?但是你如果把 x 設成 0 的話,myabs 0 會 怎樣呢?myabs 0 的話呢,x 是 0,對不對?那 0 有小於 0 嘛? 有沒有?沒有。 0 有大於 0 嘛? 沒有。 所以它就會跑到這裡來。 沒有東西,沒有東西了呢,這個函數就停止執行,停止執行之後,它就會傳回一個 none,對不對?好,那所以你就會發現這個 奇怪的狀況,就是說呢,欸 myabs 0 suppose 應該傳回 0 的,但是它卻傳回 none。 那就是一個 bug,對不對。 怎麼修呢?這個修 這個處理其實也很簡單,對不對?那 事實上呢,你只要在前面的這個函數的 這個定義裡面呢,這個你把等號加進去就好了嘛,對不對? 好,不管你是加這邊或者加這邊都可以。 那我們現在就加這邊,對不對。 好。 那我們加這邊之後呢,就是所有的這個 小於零大於零等於零的 case 我們都處理掉了,對不對? 然後呢,所以這時候呢,這個輸出的東西就會對的,這個東西 就會印出 3.5,這個東西就會印出 0。