Introduction embedded systems docker

Hi everyone joining the course Introduction to Embedded Systems Software and Development Environments on Coursera. I found that installing VirtualBox according to the suggestion required downloading a large file and setting up the environment. Instead, I am sharing the steps to set up the environment for the course using Docker.

Step 1: Install Docker

Get Docker Desktop

Step 2: Pull and run the Docker image

$ docker run -d  ubuntu:22.04 sleep 8640000

Step 3: Access the Docker containe

$ docker container ls

You will see the container ID and the name of the container. Use the container ID to access the container.

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6ec4514d27ee ubuntu:22.04 "sleep 864000" 16 hours ago Up 16 hours wizardly_nightingale
docker exec -it wizardly_nightingale /bin/bash

Step 4: Install the required packages

Now you are inside the container. Install the required packages.

$ apt install build-essential unzip gcc-arm-none-eabi

You are all set to start the course. Enjoy learning!

Passkey

來到了2024年,你還在用一個密碼登入所有網站嗎? 來看看 Passkey 可以怎麼幫助你。

首先,我們來看看密碼的問題: - 你有多少個密碼? - 你的密碼有多長?

我們都聽密碼要長,要複雜,但是你真的能記得所有密碼嗎?許多人會用相同的密碼登入不同的網站,這樣一旦有一個網站被駭客入侵,你的所有帳號都會被盜走。

你可以去 haveibeenpwned 這個網站看看你的密碼有沒有被外洩過,如果有,你就應該趕快換掉。因為根據統計,有81%的資料外洩事故跟遺失密碼有關Report

現在我們了解到密碼的問題,那麼 Passkey 可以怎麼幫助你呢?密碼學家發明了公鑰加密,一個簡單的解釋是,你可以產生一組公鑰和私鑰,你可以把公鑰給別人,別人可以用公鑰加密訊息,但是只有你的私鑰可以解密。這樣你就不用擔心密碼被盜了。比如說Bob公開了他的公鑰P,Alice用P加密了一個訊息M,只有Bob的私鑰S才能解密M。這樣子Alice就可以驗證這個訊息是Bob發出的。

為了方便使用,我們可以使用Google或是Apple的Passkey,這樣你就不用自己管理公鑰和私鑰了。

首先,我們來看看Google的Passkey怎麼設定: 在你的手機上登入 Google的帳號,點選進入 Passkey,然後點選"取得密碼金鑰",之後就可以利用手機的指紋或是臉部辨識來登入你的帳號。

設定完Passkey之後,我們來看看如何使用Passkey登入網站,以下是露天拍賣的設定步驟。用手機網頁或是露天App進入登入後就可以設定。

既然Passkey這麼方便,為什麼不試試看呢? 目前唯一的理由就是支援Passkey的網站還不夠多,但是隨著時間的推移,我相信Passkey會變得越來越普及。

Advent of code

一年一度的 Advent of Code 又開始了,今年是我第一次參加,正好用來練習 Elixir。

Advent of Code 是馬拉松競賽,連續 25 天每天都有一個問題,每天的問題都會有兩個部分,第一部分的問題比較簡單,第二部分的問題會比較難,而且第二部分的問題會跟第一部分的問題有關聯。相對其他程式競賽,Advent of Code 有一個地方很特別,那就是他第二部份的問題的 Input 跟 第一部份是相同的,只是題目會比較難。 做了幾天題目之後,我在解第一部份的問題時,會先猜猜看第二部份的問題會是什麼,然後再來寫第一部份的程式,這樣第二部份的問題就會比較好寫了。

以下分享一些解題心得。

Day 3

Part 1

觀察到每個 row 可以獨立計算,利用兩層迴圈,第一層迴圈是 row,第二層迴圈是 column,從左到右,遇到符號的時候,就把數字記起來。比如說,row的值是

..123*..
. => 0
. => 0
1 => 1
2 => 12
3 => 123
* => 123

當讀到*的時候,就知道把數字是123,因為123旁邊有符號,所以把這個數字記起來。

Part 2

跟 Part 1 一樣,只是要多做一件事情,就是紀錄每個符號連結到的數字有哪些,最後找出連結到兩個數字的符號,然後把這兩個數字相乘。

Day 3 的 source 在 GitHub 上,有興趣的朋友可以看看。

Datascience elixir

Elixir 也很適合資料科學的應用,這篇文章會介紹 Elixir 的資料科學生態系統。

首先我們快速對比 Python 與 Elixir 常用的工具:

Python Elixir
Notebook Livebook
Numpy Nx
Pandas Explorer

Learning elixir

第 N 次學習 Functional Programming Language 就上手。

不論是上古神獸 Lisp,Haskell,或是現代一點的 Scala,如果你跟我一樣嘗試過學習 Functional Programming Language,但是都沒有成功,那麼 Elixir 是你最好的選擇。

Pipe Operation - 括號終結者

我朋友 ypcat 推我入 Elixir 的坑的時候,舉出了一個 Elixir 的優點,那就是 Elixir 的語法很簡單,很像 Ruby,所以學習起來很容易,最重要的是可讀性很高,沒有一堆括號()。

比如說我們要把字串的前後空白去掉,再轉成大寫,然後把 WORLD 換成 Gary,如果用 Python 寫的話,會是這樣:

astr = " Hello world! "
astr.strip().upper().replace("WORLD", "Gary")

這邊可以看到由於 Python 支援 object ,所以字串有 strip, upper, replace 這些 method 可以用,而且這些 method 都會回傳一個新的字串,所以可以一直串起來用。

再來看一下 Elixir 的寫法:

astr = " Hello world! "
String.trim(String.replace(String.upcase(astr), "WORLD", "Gary"))

巢狀的括號看起來是不是很難懂? 這時候就可以用到 Pipe Operation 來改寫:

astr = " Hello world! "
astr |> String.trim() |> String.upcase() |> String.replace("WORLD", "Gary")

背後的原則是,我們可以把這樣的 expression g(f(x)) 改寫成 x |> f() | > g() ,這樣看起來是不是清爽多了?

Thinking Elixir 入門課程

初次學習 Elixir 的朋友, 推薦從這邊開始,有兩堂入門的課程: ThinkingElixir

如果你還沒有 Elixir 的環境,建議可以從 Livebook 開始,Livebook 是一個可以在瀏覽器上執行 Elixir 程式的環境,可以很快的上手 Elixir 的語法。

Elixir 的資料結構

先來比較一下 python 跟 Elixir 的資料結構,特別注意 Elixir 是 functional programming language,所以資料結構都是 immutable 的, 而且沒有 object method,不管是 List 或是 Map 存取都是用 function。

List

Elixir 的 List 跟 Python 的 List 很像,但是同樣的 Elixir 的 List 是 immutable 的,如果修改 List 內的值,會得到新的 List 。 另外 Elixir 的 List 不像是 Array,不能直接存取第 n 個元素。一般 List 的用途是要搭配Pattern,例如 [head | tail] ,之後再說明。

Tuple

Python 的 Tuple 跟 Elixir 的 Tuple 很像,但是 Elixir 的 Tuple 是 immutable 的。

# Python
data = (1, 2, "GO") # Python
data[0] # 1
data[2] # "GO"

# Elixir
data = {1, 2, "GO"}
elem(data, 0) # 1
elem(data, 2) # "GO"
put_elem(t, 2, "foo") # 修改第二個值會傳回一個新的 tuple {1, 2, "foo"}

Map

Elixir 的 Map 跟 Python 的 Dictionary 很像,但是同樣的 Elixir 的 Map 是 immutable 的,如果修改 Map 內的值,會得到新的 Map 。

Python: Dictionary

data = { "name" : "gary" , "age": 99 }

Elixir: Map

產生 Map

data = %{ name: "gary", age: 99, city: "Tokyo" }

注意這裡的 name 是一個 atom (:name)

讀取 Map

data[:name]

寫入 Map

Map.put(data, :name, "bob")

更新 Map

%{data | age: 31, city: "Taipei"}