如何用對數算指數為實數的值

音量單位分貝,定義是聲音的震幅每增加 10 倍,就增加 10 分貝,公式可寫成: $$ P = 10^{\frac{dB}{10}}P_0 $$ 在我們調整音量的時候,不可能每次都調大 10 倍吧?那在中間就會出現指數是小數的情況。例如我們今天若要算 $$ x = 10^{6.3} $$ 要怎麼在紙上求得近似值呢? 首先,我們改寫一下式子 $$ x = 10^{0.3} \times 10^6 $$ $$ y = 10^{0.3} $$ $$ x = y \times 10^6 $$ 這樣我們就可以先求 y,再回去求 x 了,這麼做是因為對數表上只會有 1 到 10 的值。 根據 log 定義 $$ 0.3 = \log_{10} y $$ 透過查表,找到最接近的值是 $$ \log_{10} 2.0 = 0.301 $$ $$ \rightarrow y \approx 2.0 $$ 因此 x 的值就會是...

August 21, 2021 · 1 分鐘 · wancat

如何推導 Log 換底公式

假設今天我們要算一個 2 的對數,如 $$ x = \log_2 16 $$ $$ \rightarrow 2^x = 16 $$ 我們定義 $$ 10^y=2 $$ 把第二式帶入第一式 $$ (10^y)^x = 16 $$ $$ 10^{xy} = 16 $$ 根據 log 定義,可以得到 $$ xy = \log_{10} 16 $$ $$ x = \frac{\log_{10} 16}{y} $$ 又 $$ y = \log_{10} 2 $$ 則 $$ x = \frac{\log_{10} 16}{\log_{10} 2} $$ 我們就得到了換底公式: $$ \log_a b = \frac{\log_c b}{\log_c a} $$

August 21, 2021 · 1 分鐘 · wancat

自由的伺服器測速工具 LibreSpeed 安裝教學

自己架站有時候需要了解伺服器的網速實際上有多快,這時可以在伺服器上安裝 LibreSpeed 這套軟體,打開網頁就能測連線到伺服器的速度。LibreSpeed 有 PHP 和 Go 實作,身為 Gopher 當然要用 Go 實作!本篇將以 Go 實作為範例。 Go 安裝 首先要安裝 Go,到 Golang 官網 下載你平台的壓縮檔,Raspberry Pi 選 armv6l,一般電腦要選 amd64,然後將其解壓縮: wget https://golang.org/dl/go1.16.7.linux-armv6l.tar.gz sudo tar -zxvf go1.16.7.linux-armv6l.tar.gz -C /usr/local 將 Go 加到 PATH 中,打開你的 Shell 設定檔(Bash 是 ~/.bashrc,Zsh 是 ~/.zshrc),在最後加入: export PATH=$PATH:/usr/local/go/bin 儲存後重開一個 shell,看有沒有成功安裝: $ go version go version go1.16.7 linux/arm LibreSpeed 安裝 下載並編繹 LibreSpeed git clone https://github.com/librespeed/speedtest-go.git cd speedtest-go go build -ldflags "-w -s" -trimpath -o speedtest main....

August 10, 2021 · 2 分鐘 · wancat

從零開始的 Nextcloud 完整安裝教學

用兩顆外接硬碟組 RAID 1,設定 DDNS、Nginx,並安裝 Nextcloud,以及後續的 PHP 調校與 Redis 快取。

August 7, 2021 · 8 分鐘 · wancat

過早的優化是萬惡的根源

有次我要開發一個規劃時間的演算法,需要將時間切割成一個一個單位做計算,這時普通的作法會是用布林陣列來儲存每個時間點,然而我需要對時間做一些 AND、OR、NOT 的布林運算,我當時突發奇想,假如用 BigInt 來儲存效能和記憶體都會省下不少,意思是將一個整數視作一個布林陣列,每一個位元就代表一個時間單位,這樣相比用布林陣列,足足省下至少 8 倍的記憶體。我心裡覺得這真是太酷了,於是就一股腦開發基於 BigInt 的演算法。 BigInt 由於本來就不是陣列,不論是讀值、改值都相當因難。以讀取第 i 項的值為例,需要寫成: // normal index array[i]; // bigint index const n = 0b10111000; (n >> i) % 2; // ??? 看起來不直觀、可讀性差、又容易出現差一錯誤。debug 時也相當難纏,直接把 BigInt 印出來,會得到一個巨大十進位整數(本來它就是 Big Int 嘛),需要額外呼叫方法將其以二進位顯示,後來我還將其封裝成一個類別,花了好大力氣寫 unit tests、各種 debug function,最後終於將演算法給實作出來了,花了整整兩週的時間(side project 嘛)。 正當我得意於自己的成果時,遭到現實衝擊——我們使用 React Native 來開發 Mobile App,而 BigInt 是新語法,React Native 還沒有支援。我耗費好幾個小時嘗試各種偏方,然而都不得好轉,最後在無耐之下只好將演算法用陣列重寫。原先以為會天崩地裂、再花上一週的時間,然而由於我有非常多的單元測試,我竟然只用一個下午就將整個演算法改寫完了,比我研究如何在 React Native 跑 BigInt 的時間還少,而改寫後程式的可讀性也提升了不少,那效能呢?由於這是個跑在 client 端的演算法,效能根本不重要,使用體驗毫無差別,省下那一點點記憶體也一點用都沒有。 「過早的優化是萬惡的根源」,在不存在效能瓶頸時就做優化,結果適得其反。比起效能,應該以可讀性優先。 此外,單元測試真的很重要。

August 3, 2021 · 1 分鐘 · wancat

在 Python 中實作對話型聊天機器人

當你在開發一個聊天機器人,有時候為了使用者體驗,你不能要使用者用像指令的方式,將所有資訊一次傳過來。舉例來說,若我們要開發一個猜數字遊戲運作如以下: user: guess bot: From what number? user:: 25 bot: To what number? user: 100 bot: Guess a number between 25 to 100 user: 64 bot: too small user: 91 bot: too large …… user: 83 bot: Correct! You spent 6 times to guess this number. 然而,我們在後端通常是「一個請求一個回覆」,如果要將這樣的行為拆成多個 handler 將會是場災難,為什麼?想想要怎麼存狀態,全域變數?資料庫?還是 Redis?每當你多問使用者一個問題,你就得在你的 state schema 新增一個欄位,讓你的程式碼越來越複雜。 接下來,我會告訴你如何用一個非常輕鬆的方式處理對話,讓你只要寫像以下一般的程式碼就能達成。 def guess(self): '''Game function''' min_value = self.ask_number('From what number?') max_value = self.ask_number('To what number?') secret = randint(min_value, max_value) msg = f'Guess a number between {min_value} to {max_value}' counter = 0 while True: counter += 1 answer = self....

July 29, 2021 · 3 分鐘 · wancat

基本收入不能解決貧富差距,又如何?

當我們用「翻轉」一詞,其實就已經隱含了單一的價值觀:有錢就是高社會階級

July 8, 2021 · 1 分鐘 · wancat

Django 將 Stdout 導向 Streaming Response

有時候後端要執行一個時間比較長的任務,而任務內容極為複雜,又容易出錯,因此希望讓使用者看到即時的 console log,讓我們函式中的 print 輸出能即時傳到使用者的瀏覽器。 以下將會以 Django, Thread, Queue 進行實做 StreamingHttpResponse 一般的網頁請求都是一次打包好所有資料,全部傳給使用者,有些情況我們不能等到所有資料準備好才一次傳,而要拿到一些就傳一些,這個時候我們就要使用串流輸出,在 Django 裡,就是使用 StreamingHttpResponse,以下簡稱 SHR。SHR 接收一個 Iterator 作為輸入,因此我們只要實做一個迭代器函式,其中每次 yield 就會由 SHR 傳送到瀏覽器 # Example of StreamingHttpResponse from django.http.response import StreamingHttpResponse def example(): for i in range(5): # Add <br> to break line in browser yield f'{i}<br>' def stream(request): return StreamingHttpResponse(example()) Output (in browser): 0 1 2 3 4 Thread 由於我們的程式需要一邊執行目標任務,一邊串流輸出,因此需要平行化執行。Python 中可以使用 threading, multiprocessing 等方式做平行化執行,本文將使用 threading。 # Example of threading from threading import Thread import time def example(times): for i in range(times): print(i) time....

May 25, 2021 · 3 分鐘 · wancat