2024年4月30日 星期二

不斷電指示燈

http://4rdp.blogspot.com/2024/04/blog-post_30.html?m=0

不斷電指示燈結構

個人擔任社區機電委員,發現每年有數十個不斷電指示燈故障需要更換,每年花在這裡的費用差不多三、四萬元,想研究看看這些指示燈故障的原因以及如何節省開支,因此請總幹事留下故障的燈具,經過拆解檢查發現問題都是在充電電池上面,其實只要換掉這些電池,都可以再使用。

不斷電指示燈的運作方式,平時接市電,電路控制板會驅使 LED 發光照明,並且也會對鎳氫電池充電,一但停電,控制電路會自動切換成由電池供電,以及連續照明時間可達 1.5 小時以上。

這樣簡單的電路為什麼電池會壞掉?問題在鎳氫電池 (Ni-MH),它長時間充電,如果過度充電會使電池老化,從充電電路設計來看,它應該是採用涓流充電,因此三五年時間一到,再經過幾次室內停電放電充電,這些電池都會壞掉。此外,鎳氫電池還有充電記憶效應以及自放電 (漏電) 問題,所以電池老化更換是不可避免的。

2024年4月26日 星期五

數學之美 24 ─ 單一不規則拼圖

http://4rdp.blogspot.com/2024/04/24.html?m=0

    圖片來源 Scientific American

看到這種單一不規則圖塊可以拚滿整張圖,感到驚奇。

2024年4月22日 星期一

訓練數學感 371 ─ 求面積

http://4rdp.blogspot.com/2024/04/371.html?m=0

求灰色三角形面積。

難度 ✩✩

2024年4月18日 星期四

Pytest

http://4rdp.blogspot.com/2024/04/pytest.html?m=0

最近公司 PXI 新儀器開發完成了,終於有時間可以整理一些技術文章,以便日後需要時能夠快速查閱,這一篇文章記錄 pytest 指令常用用法,pytest 是一個 Python 自動測試模組,可以用來判別與記錄測試結果相不相符。

首先 Python 需要安裝 pytest 模組,開啟 Command Prompt,輸入 DOS 指令,

> pip install pytest

然後撰寫一個 Python 程式,但是檔案命名須為 test_XXX.py,程式內依據測試項目再寫出相關的小程式,每一個小測項名稱也是要以 testZZZ() 來命名,每個小程式盡量 50 行以內不要太大,
import pytest

def test1():
    b = 'Apple'
    assert b != 'Hello'    # PASS
    
    a = 1
    assert a == 0          # FAIL 1
    print('--------')      # 上一行錯誤後,從這一行開始就不會被執行
    assert b != 'Apple'    # FAIL 2


def test2():
    b = 'Apple'
    assert b != 'Hello'    # PASS
    
    a = 1
    #assert a == 0          # FAIL

最後執行 pytest 即可,

> pytest

上面指令會測試工作路徑下,包含所有子目錄中檔案名字有 test 的 Python 程式,

> pytest .\path\test_YYY.py > .\path\data.txt

上面指令可以指定特定程式執行,而後面黃色部分可以將螢幕輸出內容存成檔案,方便後續分析問題原因。


接下來介紹進階用法,首先為選項用法,這需要另外新增一個 pytest.ini 檔,否則會出現警告訊息,不過沒有 ini 宣告,也是可以執行。
[pytest]
markers = 
    AAAonly: test cases only for AAA.
    BBBonly: test cases only for BBB.

此外 Python 程式需要加入 @pytest.mark,
@pytest.mark.AAAonly
def test1():
    b = 'Apple'
    assert b != 'Hello'    # PASS
    
    a = 1
    assert a == 0          # FAIL 1
    print('--------')      # 上一行錯誤後,從這一行開始就不會被執行
    assert b != 'Apple'    # FAIL 2


@pytest.mark.BBBonly
def test2():
    b = 'Apple'
    assert b != 'Hello'    # PASS
    
    a = 1
    #assert a == 0         # FAIL

指令需加入 -m 參數,這樣可以指定哪些項目要測試或是不測試,

> pytest test_try.py -m "not AAAonly"


指令加入 -s 參數,可以將程式內 print() 的內容顯示於螢幕上,

 > pytest -s


如果某項目不測試,也可以使用 @pytest.mark.skip,例如
@pytest.mark.skip(reason='太累了,不想測!')
def test0():
    c = 0
    assert c != 0

第二個是參數用法,如果測試時需要變換參數檢查各式條件,請用這方法,它比在程式內使用 for loop 好,可以很容易知道在測試哪個條件時異常,請使用 @pytest.mark.parametrize,
@pytest.mark.parametrize("num", [0, 1])
def test3(num):
    assert num == 0           # check number

它可以多參數同時引入,方法如下,
@pytest.mark.parametrize("index, value, unit", [
                        ( 1,      0.1,   'V'),
                        ( 2,      1.0,   'A'),
    ])
def test4(index, value, unit):
    print('')
    print(f'Index = {index}, Set {value}{unit}')

當你想巢狀測試多個參數,可以用下列的方法,
@pytest.mark.parametrize("num", [0, 1])
@pytest.mark.parametrize("word", ['Apple', 'Hello'])
def test5(num, word):
    assert num == 0           # check number
    assert word != 'Hello'    # check word

pytest 的用法不只這些,有興趣的人可以再研讀 https://docs.pytest.org/ 技術文件。

2024年4月14日 星期日

重力加速度 g 與圓周率 𝞹

http://4rdp.blogspot.com/2024/04/g.html?m=0


這部影片除了介紹開根號的方法,另一個重點在地球的重力加速度是圓周率的平方!

重力加速度 g 和圓周率 𝞹 的關係來自單擺周期運動,因為

$T=2\pi \sqrt{\frac{l}{g}}$

當單擺週期為 2 sec,繩長 1 m 時,兩者的關係就是 𝞹 = √g

另外影片介紹的第一種開根號,就是長除式演算法,至於影片解說計算機計算開平方根的方法使用泰勒展開,這絕對是大錯特錯,因為我寫過組合語言計算根號,它是用長除式演算法,用二進制來算而不是十進制來算,十進制要每位 0 ~ 9 試錯求解,可是二進位只要檢查 1 會不會溢位,即可決定每一位是 0 還是 1。例如
27 = 01 10 11b   十進位轉二進位

                 (2a+b) b
   __1__0__1____     
  / 01 10 11
     1________   (2x   0 + 1) x 1 = 1
       10 11   
        0_____   (2x  11 + 1) x 1 = 111 > 10
       10 11
       10 01___  (2x 100 + 1) x 1 = 1001 < 1011
          10
從上面算是可以看出整數 27 開根號可得整數 5 餘 2,這方法比泰勒展開簡單多了,效能又好。

另外,迭代計算是逼近數值的好方法,例如

X = A

開根號的迭代式為
 
Xn+1 = (Xn + A/Xn)/2  ......... (1) 參考牛頓迭代法

   或是

Xn+1 = Xn + (A-Xn²)/Xn/2  ..... (2) 參考快速估算根號近似值


2024年4月10日 星期三

訓練數學感 370 ─ C 視力表

http://4rdp.blogspot.com/2024/04/370-c.html?m=0

左圖為 C 視力表,通常受試者站在表前 5 公尺,指出 C 字缺口方向來檢查視力,關於 C 字缺口大小 Y 和 視力 V,兩者成反比關係, VY = 1.5
例如視力 V = 1.0 則缺口 Y = 1.5 mm

因為測試場地不夠大,只有 4 公尺長,有個人可以看到缺口 Y = 1.0 mm 那一排,請問他的真實視力為何?

難度 ✩✩

2024年4月6日 星期六

電阻阻值

http://4rdp.blogspot.com/2024/04/blog-post.html?m=0


為什麼常見 E6 電阻 (±20%) 數值是 10、15、22、33、47、68 呢?

這是因為要讓數值之間呈現等比級數增加,經過六個數字後為原來的十倍, $\sqrt[6]{10}\approx 1.5$
並且計算誤差可以含括所有範圍,如
10 x 120% = 12
15 x 80% = 12

其它細節詳見 YouTube 影片。

2024年4月2日 星期二

數學之美 23 ─ 質數圖

http://4rdp.blogspot.com/2024/04/23.html?m=0


這是一個 517 位數的質數!