作者彙整: Riddle

好書推薦:《人工智慧開發實務 – 使用 Swift》

Practical Artificial Intelligence with Swift 繁體中文版

最近看了《人工智慧開發實務 – 使用 Swift》這本書,覺得這本書寫的真不錯。

不像其他有著艱澀數學與演算法的 Machine Learning 書籍,這本書是屬於實戰類型的書,只用了第十章稍微說明了那些可怕的 ML 演算法,其他章節則教你如何使用 Apple 系統內建的 framework 來做電腦視覺 (Vision)、自然語言處理 (Natural Language)、聲音分析 (Sound Analysis),語音識別 (Speech) 等功能,還有如何使用 CreateML 等工具來訓練自己的 ML 模型。

而且這本書提供了大量的範例程式碼,所以可以很容易的把那些功能運用在現有的 App 上。

這本書真的大推呀!👍 👍 👍

減肥人生

因為胖到危及健康了,所以開始騎單車運動,只是我習慣邊騎車邊想事情,所以常常會忘記自己騎到第幾圈了,所以寫了一個 iOS app 幫我自動計數騎了幾圈… XD

Taipei Maps – 台北生活的工具地圖

我寫了一個 Mac 版的地圖 app:Taipei Maps。

這個 app 目前使用了這些資料集:

  • 公共飲水機
  • 自來水直飲臺
  • Taipei Free 熱點
  • 自行車停放區
  • 垃圾清運點位 (垃圾車)
  • 行人清潔箱 (垃圾桶)
  • 台北市公廁
  • 新北市公廁
  • 郵局營業據點

可在地圖上查看這些資料的位置與相關資訊。

程式碼在此:https://github.com/wlmaplab/TaipeiMaps

電子專案》使用 iPhone 的 Touch ID 搭配 Arduino Nano 33 解鎖自己的電腦

最近把以前一個用 B4i 寫的 iOS app 用 Swift 重寫,功能是:用 iPhone 的 Touch ID 解鎖自己的電腦。這個程式的原理很簡單,是用一塊 arduino 模擬成 HID Keyboard,然後 iOS app 透過 BLE 把密碼傳送給 arduino 裝置,接著 arduino 裝置再把密碼輸入到電腦,利用這種方式解鎖電腦。

HID Keyboard 的部分,以前是用 Blend Micro 來做,這次則改用 Arduino Nano 33 IoT 來做。

左邊紅色的電路板是 Blend Micro,中間深藍色電路板是 Arduino Nano 33 IoT。

以下是 Demo 影片與 Source code 連結:

詳細情況請看:https://github.com/kyumdbot/AutoPass

給定一個正規表達式,找出符合這個正規表達式的所有字串

唐鳳FLOLAC’14 的演講裡有提到這個為 Apple Siri 寫的 Haskell 套件:https://github.com/audreyt/regex-genex,作用是給定一個正規表達式,找出符合這個正規表達式的所有字串,我想找找看 Python 跟 R 裡頭有沒有類似的套件,有搜尋到 Python 裡有類似的套件:https://github.com/google/sre_yield

目前還沒找到 R 的版本,希望有人知道的話能告訴我,感謝!

老 MacBook 裝 x86 Raspbian

最近把老舊的 MacBook 2010 的 RAM 加到 8GB,然後把作業系統改裝 Raspberry Pi Desktop (x86 Raspbian),有這台機器又活起來的感覺!嗯…也許是我還蠻習慣 Raspbian 的關係吧 (?

不過因為 MacBook 的螢幕太亮,而 LXDE 沒有內建調整螢幕亮度的軟體,所以需要自己手動更改螢幕亮度值,螢幕亮度的設定檔通常會放在 /sys/class/backlight/{顯卡類型之類的}/ 目錄裡面,例如我的 MacBook 2010 的螢幕亮度設定檔就放在 /sys/class/backlight/nv_backlight/ 裡,設定檔名稱通常是叫做 brightness,同個目錄下還會有一個叫做 max_brightness 的檔案,這個檔案可以看亮度最大值是多少,像我的 max_brightness 裡的數值是 100,所以我在修改 /sys/class/backlight/nv_backlight/brightness 的數值時,範圍就是 0 ~ 100。

要更改螢幕亮度時,用 nano 或是 vim 開啟設定檔,然後修改數值即可:

$ sudo nano /sys/class/backlight/nv_backlight/brightness

不過每次這樣改好像有點不直覺 (其實是我都會忘記設定檔的目錄路徑 XD),所以我寫了一個 GUI 小程式,用來調整我的 MacBook 2010 的螢幕亮度:https://github.com/kyumdbot/rpd-brightness

Kotlin’s Nullable vs. Swift’s Optional

最近在學 Kotlin 與重學那個學過但沒有學會過的 Swift,發現 Kotlin 的 nullable 與 Swift 的 Optional 非常像,大概有 87 分像吧 (不能再低了)? 所以我做了個對照表:

補充說明:

  1. 使用 ?.as? 運算子時,傳回值的型態一樣會是 nullable (Kotlin) / Optional (Swift),所以對傳回值的後續處理一樣要用 nullable (Kotlin) / Optional (Swift) 的方式對待之。 (心法:只要傳回值有可能出現空值 ( null / nil ),那個傳回值就會是一個 nullable / Optional 。)
  2. Swift Optional 的驚嘆號 ( ! ) 表示直接把 Optional 變數解包並當成有值去對待,所以當變數是空值 (nil) 的時候,對空值調用方法 (或者說:發送訊息) 時當然會當掉,因為空值無法響應那個方法。例如這行程式:str!.uppercased(),當 str 裡是一個 String 的時候,對它調用 .uppercased() 方法是沒問題的,可是當 str 裡是 nil 的時候,這時就會出錯了,因為 nil 沒有 .uppercased() 這個方法,所以會當掉。Kotlin 的 !! 符號是非空斷言 (Not-Null Assertion),告訴編譯器這個地方出現的值不會是 null,所以編譯器會把它當成非空型態去處理,但是,如果這個值不幸是 null 的話,就會拋出一個例外。
  3. Kotlin nullable 與 Swift Optional 不一樣的地方在於:Kotlin nullable 不是一個實際的 Type,例如這行 Kotlin 程式:var str : String? 表示 str 實際上的 Type 會有兩種情況:String 或 null,所以 str 變數的值有可能是一個字串,也有可能是一個空值。但是在 Swift 裡,這行程式:var str : String? 表示 str 的 Type 是一個 Optional,str 變數的值就是一個 Optional,只是這個 Optional 裡的內容可能是一個字串,也可能是一個 nil。也就是説:當一個變數的值可能出現空值時,Swift 用 Optional 去封裝那個變數;但在 Kotlin 裡,把變數宣告成 nullable 的型態時,只是在告訴編譯器,這個變數有可能出現空值 (所以這個變數的 Type 實際上可能會出現兩種情況),然後編譯器就會對這個變數做可空型態的檢查,確保程式碼裡有把出現空值的情況考慮進去。

Haskell 筆記》Currying function

在一般 C-like 的程式語言裡,如果想寫一個函數把兩個整數相加,並傳回相加後的結果,通常會這樣寫:

int add(int a, int b) { 
    return a + b; 
}
function add(a, b) {
    return a + b;
}

但是在 Haskell 裡會這樣寫:

add :: Int -> Int -> Int
add a b = a + b

第一行的 add :: Int -> Int -> Int 是描述函數的型別,第二行的 add a b = a + b 是函數的主體。

我第一次看到這種寫法時,覺得這種寫法看起來很怪,尤其是第一行,為何前兩個參數的分隔符號是用 -> 呢?

Haskell 的 -> 符號的含義: -> 符號表示一個函數,這個函數接受左側型別的參數,並返回右側型別的值。

後來才明白這種寫法的奇妙之處,因為這個函數是一個柯里化函數 (Currying function)

先在 GHCi 裡輸入並執行這個函數:

:t:type 的縮寫,這個指令可以查看一個值的型別,這裡可以看到 x 的型別是 Int,add 函數的型別是:Int -> Int -> Int 。

當給 add 函數兩個整數時,會傳回兩數相加的結果,但是,我們可以嘗試只給 add 函數一個整數

由上圖可以看到,我只給 add 函數一個參數(8),並將回傳結果存到 f,然後查看 f 的型別,會發現 f 是一個函數,型別是:Int -> Int。

這裡的 f 是一個「接受一個 Int 參數並傳回一個 Int 值」的函數,f 會把傳給它的整數加 8,並回傳相加的結果。

如下圖所示,當給 add 函數兩個參數時,傳回一個 Int 值:

如下圖所示,只給 add 函數一個參數時,傳回一個函數:

Haskell 用這種語法描述函數,真的很精妙啊!