2022年10月5日 星期三

購買大薪瓦時計電表與插座配電盒

今天下午請假去署立醫院替阿蘭門診, 因上周養護中心帶她去看泌尿科發現有膀胱結石, 醫師自動掛號今天下午叫我去門診談一下是否要住院用雷射把結石清掉, 曾醫師說雖然不是必要, 但對接導尿管的人而言確實較容易引發尿路炎, 就敲定 10/18 日辦住院一兩日.

從醫院出來回鄉下家途中經過小漢, 進去買了一個上周找到的大薪瓦時計, 型號 DEX1350, 單相三線式 110/220V, 10(50) A, 60 Hz (2021 年出廠), 價格 750 元 : 





雖然露天有找到 650 元左右的, 但那是 22018 年出廠, 加上運費也差不多 700 出頭, 乾脆就在小漢買就好了 (電錶怕摔) :


除了電表還買了配線用的插座盒, 關關, 插座, 分電匯流排等, 總共花了 1046 元 : 




插座盒買兩個, 另一個插座盒其實是要來放 ESP8266 智慧開關用的. 回到家就先去勘查看看插座開關盒安裝位置, 決定逕放在原台電插座盒旁邊.

露天購買太陽能板安裝工具

最近要動手安裝太陽能儲能系統, 需要一些工具 : 

1. 壓線鉗 :





2. MC4 扳手 :





MC4 接頭作法參考 : 

太陽能 ▼ 小型太陽能組裝 ▼ 速學小型太陽能板的安裝跟配置

2022年10月4日 星期二

DeepL : 英文作文翻譯的好工具

昨天幫二哥看專題報告的英文摘要, 題目就是暑假去國家半導體實驗室上課所設計的放大器, 其實近幾年 NLP 在機器學習基礎上呈現飛躍式進步, 現在的 Google 翻譯已經翻得很不錯了, 早已不是十年前哩哩落落的光景可比, 一般來說直用也可以. 不過對於論文報告而言還是需要人工潤飾一遍比較好. 

我已經長達十年沒在英文上用功, 幫人翻譯論文摘要已是二十年前的事了, 寶刀已老看起技術文章已有點吃力, 不過還好找到下面兩個線上工具幫了大忙, 第一個是 DeepL 翻譯, 介面跟谷歌翻譯很像, 從簡體介面看應該是厲害國的 : 





翻譯結果可以跟 Google 翻譯互相參酌, 看看何者為宜, 基本上術語通常都需要視領域用法修改, 不管是 Google 或 DeepL 的術語不一定正確. 

另外一個是 DeepL 的辭典 Linguee, 可輸入單字或詞語查詢其用法 : 





底下的外部資源會列出語料庫中的句子, 可從上下文推敲用法 : 




上周末回去鄉下書櫃找我以前買的兩本方克濤寫的英文論文寫作書籍, 發現都被白蟻啃蝕掉了, 好可惜, 等我安裝完太陽能系統再來收拾白蟻. 

2022年10月3日 星期一

綠能學習與實作筆記

最近在規劃頂樓的儲能型太陽能發電系統, 來回查詢之前的筆記時順便把索引也做起來 : 


綠能含括水力, 風力, 與太陽能, 我曾經很迷風力發電, 但玩過的前輩說, 居家綠能還是以太陽能比較實用, 風力非常不穩定 (除非住在西海岸或澎湖海邊). 

2022年10月2日 星期日

2022 年第 40 周記事

爸的 OPEL ASTRA 老車前幾天開到一半引擎蓋冒煙, 剛好才路過阿文的利信保養廠不遠, 馬上掉頭開去檢修, 換了零件後叫爸回家水箱補水即可, 爸說他加完後居然引擎發不動, 我問是加哪裡, 聽完研判爸是搞錯地方, 把水加到機油管去了. 阿文將車又拖回廠裡清理, 說這車 20 多年了, 這次修一修要好幾萬不划算, 建議直接報廢, 爸一直懊悔老眼昏花居然加錯地方, 弄垮了一台車, 我說報廢也好, 最近幾年三不五時小修, 修理費也花了不少, 況且之前交通部才修訂規則, 高齡駕駛人須重考駕照, 那時小舅就叫爸別開車了, 但這台 OPEL 又還可以開, 那就繼續用唄. 

周六下午去愛心回途經過保養廠, 發現 OPEL 還停在保養廠靠路邊的停車場, 就拍了一張相片 : 




前幾天收到公司人資 email, 表示因應國門開放, 居家上班除特殊原因簽報者外, 自 10/13 起取消, 所以 10/13 我得開車把辦公室電腦載回公司, 恢復朝八晚五的生活了. 居家辦公快五個月, 我已從排斥到適應, 最後喜歡這種自由的工作方式, 雖然每天要交工作報告有點煩, 但不用趕八點刷卡奔波還不錯, 軟體業就是這種遠距工作型態吧? 感覺以後退休可以正式投入這行業, 呵呵. 

本周學習部分持續著墨在 Matplotlib OOP 部分, 原本今天能把最後一篇 (下) 寫完, 但下午在頂樓忙儲能型太陽能板安裝前的配線規劃, 勘查線路要如何拉到樓下車庫, 下午又出去鎮上的五金行買三分管用來走線, 所以都沒時間動手測試, 希望這兩天能竣工. 

本周五去河堤健走時終於拍到明誠橋下的那隻浪浪貓的長相了 : 




2022年10月1日 星期六

捐血 250 cc

早上去河堤還書, 走出圖書館要回家時發現裕誠路口停了一輛 "崑庭號" 捐血車, 我去年底捐過一次, 今年以來時不時看到路邊有捐血告示, 但不是周日就是剛好要去辦事沒空, 今天其實也是, 因為打算還完書就出發回鄉下, 路經牛將麵店買牛肉麵回去給爸, 但捐血會耗掉一些時間, 回到鄉下怕過了 12 點. 但看看似乎沒人排隊, 車裡人也不多, 就捲起袖子捐吧! 




今天的禮物是一盒養生蛋, 領完就趕緊回家拿了書跟筆電就馬上出發回鄉下, 還好一路順暢回到家剛好 12 點, 中午跟爸兩人大啖牛肉麵, 捐了血是該補一下氣血. 

購買 BatteryTender 120W 變流器

前天在臉書太陽能社群看到 505 電工坊標售 BatteryTender 120W 變流器, 我在結標前半小時看到時已出價至 570 元, 想說等結標前幾分鐘出價 640 就行, 哪知陸續有人出價到 750 (懷疑該不是老闆用其它帳號出價吧?), 我查了一下露天與蝦皮售價都在 1000 元, 所以在最後一分鐘出了 820 得標, 比市價低了 180 元, 昨天去忠孝路取貨. 




這款低功率變流器是點菸器接頭, 適合用來在車上充筆電, 如果要接電池須轉接筒 (約 180 元). 我想找時間測試看看接汽車救援行動電源是否能驅動家中須插電的櫻花熱水器, 這樣萬一停電還可以洗熱水澡 (買熱水器最好是選電池點火的).

市圖還書 3 本 (用Excel學Python資料分析)

 今日去河堤還下列 4 本書 : 
三本都被預約了, No.2 目前沒時間玩物聯網, 等以後有空再回借. No.3 是講用 Pandas 取代 Excel 的好書, 值得一讀再讀 (這本母校圖書館也有). 

好書 : 線上教學的技術-快速上手的12堂必修課

 此書已大致看完, 因有人預約所以先做個筆記後還書. 


Source : 博客來


作者王永福是專業培訓教練與講師, 這本書不是在講如何操作線上教學軟體, 而是 "線上教學的技術", 把實體教學的技術搬到線上同樣成功. 
  1. 線上課程非常容易分心, 必須避免單純講課, 一定要把內容變成互動模式, 例如舉手回答 (問答法), 單選複選 (選擇&排序法), 小組討論, 遊戲化 (演練法) 等. 
  2. 線上教學核心策略是 : 最小化技術需求, 最大化教學效果.
  3. 講述法效果要好, 投影片的輔助很重要, 其三大技巧是 : 大字流, 半圖文, 全圖像, 最重要的關鍵是 : 講到時才出現投影片. 
  4. 選擇與排序法可一次對多人, 事先請學員準備半張 A4 紙, 講師利用投影片出題目, 然後請大家寫答案, 對答案, 用最簡單的工具與方法就可以創造互動參與. 
  5. 演練法是說給你聽, 做給你看, 讓你做做看. 最重要的是要有示範, 其次是指令要清楚, 甚至要多次重覆. 
  6. 影片法只是教學輔助, 而非教學主體. 影片一定要短且聚焦, 播放前後要有提示重點或有學習活動. 
  7. 教學的本質是教學成效, 想辦法用最簡單的工具完成最有效的教學, 以最小化的資訊需求 (白紙與粗筆) 最大化教學成果. 但如果要做小組討論就需要軟體提供的功能.
  8. 教學中加入遊戲元素可增加參與動力, 但遊戲化並非真的要玩遊戲, 而是把遊戲的 PBL 三大元素 (Point 點數, Benifit 獎勵, Leaderboard 排行榜) 融入教學教學過程中, 另外, 遊戲規則, 公平, 即時回饋等也很重要.

2022年9月30日 星期五

Python 學習筆記 : Matplotlib 資料視覺化 (六) 物件導向篇 (中)

因為篇幅太長, 所以把物件導向拆成三篇, 本系列之前的測試文章參考 : 


四. 使用 GridSpec 物件為子圖排版 : 

前一篇物件導向 (上) 的測試中, 不論是呼叫 fig.add_subplot() 或 plt.subplots(), 子圖都是以網格矩陣排版, 沒有放置子圖 AxesSubplot 物件的那一格會出現一個空缺, 沒辦法合併儲存格. 在進階篇中有介紹合併儲存格的做法, 但那只能整列或整欄合併. 如果要對網格作較彈性的儲存格合併來排版, 必須以物件導向模式使用 GridSpec 類別的物件來設定版面, 參考 :


GridSpec 類別放在 Matplotlib 的 gridspec 模組中, 使用前須先匯入, 例如 : 

>>> import matplotlib.pyplot as plt   
>>> import matplotlib.gridspec as gridspec    
>>> type(gridspec)    
<class 'module'>   

首先呼叫 GridSpec 類別的建構式 GridSpec() 來建立 GridSpec 物件, 常用語法如下 :

grid=gridspec.GridSpec(nrow, ncol [figure, wspace, hspace])   

此建構式會傳回一個 GridSpec 物件. 參數說明如下 :
  • nrows 與 ncols 表示子圖網格的列數與欄數 (必要參數)
  • figure 為 Figure 物件, 用於 contrained_layout 為 True 時. 
  • wspace 與 hspace 為相對於子圖尺寸 (寬高) 之百分比做為子圖間距 (值 0~1)
以建立如下版面為例, 基本架構為 2*3 網格, 然後將右上角與左下角兩格合併形成 4 個繪圖區 :




例如建立間距是 0.4 倍子圖寬高尺寸的 2*3 網格 : 

>>> grid=gridspec.GridSpec(2, 3, wspace=0.4, hspace=0.4)   
>>> type(grid)   
<class 'matplotlib.gridspec.GridSpec'>   

注意, 不指定參數關鍵字的話, 第一參數為 nrows, 第二參數為 ncols, 為了增進程式可讀性, 最好還是指定關鍵字. 

接著建立畫布物件, 然後依據繪圖區在網格中的位置指定 GridSpec 物件的索引, 將其傳給 Figure 物件的 add_subplot() 方法來建立 4 個繪圖區 (子圖) 物件 : 

>>> fig=plt.figure()       
>>> ax1=fig.add_subplot(grid[0, 0])   
>>> ax2=fig.add_subplot(grid[0, 1:])   
>>> ax3=fig.add_subplot(grid[1, :2])   
>>> ax4=fig.add_subplot(grid[1, 2])    
>>> plt.show()   

此處 ax1 子圖位置是 2*3 網格中的第 0 列第 0 行, 故傳入 grid[0, 0]; ax2 子圖位置是 2*3 網格中的第 0 列第 1 行與第 2 行的合併儲存格, 故傳入 grid[0, 1:], 其中欄索引 1: 表示索引 1 以後全部; ax3 子圖位置是 2*3 網格中的第 1 列第 0 行與第 1 行的合併儲存格, 故傳入 grid[1, :2], 其中欄索引 :2 表示索引 2 以前全部 (不含 2, 即欄索引 0 與 1); ax1 子圖位置是 2*3 網格中的第 1 列第 2 行, 故傳入 grid[1, 2], 結果如下 : 




注意, 若傳入 GridSpec() 的間距 wspace 與 hspace 太小 (例如 0.2), 可能會使坐標軸刻度標籤會與子圖標題部分重疊, 需要視畫布大小微調. 

完整程式碼參考 :

測試  : 使用 GridSpec 物件排版 (1) [看原始碼]


在前一篇測試中, 子圖間距的懶人設定法有兩個, 一是呼叫 fig.tight_layout() 函式讓版面緊密, 但這方法在使用 GridSpec 物件排版時無效, 而且會出現如下警告 :

>>> fig.tight_layout()   
matplotlib_fig_adjust_subplot.py:1: UserWarning: This figure includes Axes that are not compatible with tight_layout, so results might be incorrect.

第二個方法是呼叫 fig.subplots_adjust(), 這雖然不會出現警告, 但也同樣無效. 

如果不想微調 wspace 與 hspace 的麻煩, 可以在建立 Figure 物件時傳入 constrained_layout=True 參數讓版面受限制並自動調整間距, 然後於建立 GridSpec 物件時將 Figure 物件傳給 figure 參數, 例如 :

>>> fig=plt.figure(constrained_layout=True)    # 讓版面受限
>>> grid=gridspec.GridSpec(nrows=2, ncols=3, figure=fig)    # 指定 Figure 物件
>>> ax1=fig.add_subplot(grid[0, 0])   
>>> ax2=fig.add_subplot(grid[0, 1:])   
>>> ax3=fig.add_subplot(grid[1, :2])   
>>> ax4=fig.add_subplot(grid[1, 2])    
>>> plt.show() 

結果如下 : 




完整程式碼參考 :

測試  : 使用 GridSpec 物件排版 (2) [看原始碼]


除了直接使用 GridSpec 類別來排版外, 也可以利用 Figure 物件的 add_gridspec() 方法來建立 GridSpec 物件, 這樣就不需要匯入 gridspec.GridSpec 類別了. 語法如下 : 

grid=fig.add_gridspec(nrow, ncol [figure, wspace, hspace]) 

參數用法與上面的 GridSpec() 建構式一樣, 例如 : 

>>> import matplotlib.pyplot as plt 
>>> fig=plt.figure()  
>>> grid=fig.add_gridspec(nrows=2, ncols=3, wspace=0.4, hspace=0.4)    
>>> type(grid)   
<class 'matplotlib.gridspec.GridSpec'>      
>>> ax1=fig.add_subplot(grid[0, 0])   
>>> ax2=fig.add_subplot(grid[0, 1:])   
>>> ax3=fig.add_subplot(grid[1, :2])   
>>> ax4=fig.add_subplot(grid[1, 2])    
>>> plt.show() 

可見 fig.add_gridspec() 同樣會傳回 GridSpec 物件, 結果與上面用 GridSpect 物件排版的一樣.

完整程式碼參考 :

測試  : 使用 GridSpec 物件排版 (3) [看原始碼]


當然也可以用 constrained_layout 參數讓 Figure 畫布自動調節版面與子圖間距 :

>>> import matplotlib.pyplot as plt 
>>> fig=plt.figure(constrained_layout=True)      # 讓版面受限
>>> grid=fig.add_gridspec(nrows=2, ncols=3)    # 建立 2*3 網格之 GridSpec 物件
>>> ax1=fig.add_subplot(grid[0, 0])   
>>> ax2=fig.add_subplot(grid[0, 1:])   
>>> ax3=fig.add_subplot(grid[1, :2])   
>>> ax4=fig.add_subplot(grid[1, 2])    
>>> plt.show() 

結果與上面用 GridSpect 物件排版的一樣. 完整程式碼參考 :

測試  : 使用 GridSpec 物件排版 (4) [看原始碼]


更複雜的版面配置範例如下 : 




此例將 3*3 網格作局部合併成 5 個子圖, 配置時主要的工作是利用切片技巧決定各子圖的索引, 其中冒號與負號的運用是重點, 例如 : 

>>> import matplotlib.pyplot as plt 
>>> fig=plt.figure(constrained_layout=True)      # 讓版面受限
>>> grid=fig.add_gridspec(nrows=3, ncols=3)    # 建立 3*3 網格之 GridSpec 物件
>>> fig=plt.figure(constrained_layout=True)       
>>> grid=fig.add_gridspec(nrows=3, ncols=3)    
>>> ax1=fig.add_subplot(grid[0, :])   
>>> ax2=fig.add_subplot(grid[1, :-1])   
>>> ax3=fig.add_subplot(grid[2, 0])     
>>> ax4=fig.add_subplot(grid[2, 1])   
>>> ax5=fig.add_subplot(grid[1:, 2])   
>>> plt.show()  

此例使用 constrained_layout 來限制版面配置, 由畫布自動調節版面與子圖間距, 結果如下 :




完整程式碼參考 :

測試  : 使用 GridSpec 物件排版 (5) [看原始碼]


利用 GridSpec 物件可以彈性地對子圖網格進行排版, 下面是改編自 Matplotlib 官網與 "Python 資料科學學習手冊" 書中第四章的多軸值方圖範例, 參考 : 


>>> import matplotlib.pyplot as plt 
>>> import numpy as np   
>>> np.random.seed(42)                # 設定隨機種子
>>> x=np.random.randn(1000)     
>>> y=np.random.randn(1000)   
>>> grid=fig.add_gridspec(nrows=2, ncols=2, wspace=0.05, hspace=0.05)  # 2*2 網格      
>>> ax=fig.add_subplot(grid[1, 0])          # 繪製散佈圖用
>>> ax_histx=fig.add_subplot(grid[0, 0])   # 繪製垂直直方圖用   
>>> ax_histy=fig.add_subplot(grid[1, 1])   # 繪製水平直方圖用
>>> ax_histx.set_xticklabels([])  # 取消垂直直方圖 X 軸刻度標籤
>>> ax_histy.set_yticklabels([])  # 取消水平直方圖 Y 軸刻度標籤
>>> ax.scatter(x, y)                      # 繪製散佈圖
<matplotlib.collections.PathCollection object at 0x0000020AB16D0F28>
>>> ax_histx.hist(x, bins=10)     # 繪製垂直直方圖
(array([  7.,  21., 101., 194., 277., 220., 129.,  42.,   5.,   4.]), array([-3.28006281, -2.57456585, -1.86906889, -1.16357192, -0.45807496,
        0.247422  ,  0.95291897,  1.65841593,  2.36391289,  3.06940985,
        3.77490682]), <a list of 10 Patch objects>)
>>> ax_histy.hist(y, bins=10, orientation='horizontal')     # 繪製水平直方圖
(array([  8.,  24.,  69., 190., 258., 222., 164.,  49.,  13.,   3.]), array([-3.21292639, -2.54757846, -1.88223054, -1.21688261, -0.55153469,
        0.11381324,  0.77916116,  1.44450909,  2.10985701,  2.77520494,
        3.44055286]), <a list of 10 Patch objects>)
>>> plt.show()   

此例使用隨機數來繪製散佈圖與 X, Y 軸直方圖, 直方圖分成 10 個 bin (值區段), 散佈圖放在 [1, 1] 網格; X 軸直方圖 (垂直) 放在 [0, 0] 網格; Y 軸直方圖 (水平) 放在 [1, 1] 網格, 並用 set_xticklabels([]) 與 set_yticklabels([]) 拿掉直方圖的刻度標籤, 結果如下 : 




從直方圖的分布可知這近似常態分布, 如果將 bin 設大一些例如 50 就很接近常態分佈了. 

完整程式碼參考 :

測試  : 使用 GridSpec 物件排版 (6) [看原始碼]


五. 使用 GridSpec 物件為子圖排版 : 

在 "王者歸來-Python 在大數據科學計算上的最佳實作" 這本書的第四章介紹了使用 pyplot.subplot2grid() 函式配置版面的方法, 觀念與網頁 HTML 表格或 Excel 合併儲存格類似, 比上面使用 GridSpec 類別與 Figure 物件的 add_gridspec() 方法排版更直觀. 常用語法如下 :

ax=plt.subplot2grid(shape, loc [, rowspan=1, colspan=1])      

參數說明如下 : 
  • shape : 是 (列數, 行數) 組成之網格形狀 (元組)
  • loc : 子圖左上角在網格中的座標位置, 以 (列, 行) 元組表示
  • rowspan : 子圖所佔行數, 即橫向合併格數
  • colspan : 子圖所佔列數, 即直向合併格數
此函式還有其它關鍵字參數, 用法與 Figure 物件的 add_subplot() 方法相同. 此函式會傳回一個 AxesSubplot 物件, 例如 :

>>> import matplotlib.pyplot as plt  
>>> fig=plt.figure(figsize=(8, 6))     
>>> ax1=plt.subplot2grid((3, 3), (0, 0), colspan=2)   
>>> type(ax1)   
<class 'matplotlib.axes._subplots.AxesSubplot'>      
>>> ax2=plt.subplot2grid((3, 3), (0, 2), rowspan=2)   # 直向合併 2 格
>>> ax3=plt.subplot2grid((3, 3), (1, 0), rowspan=2)   # 直向合併 2 格
>>> ax4=plt.subplot2grid((3, 3), (2, 1), colspan=2)     # 橫向合併 2 格 
>>> ax5=plt.subplot2grid((3, 3), (1, 1))   
>>> ax1.text(0.5, 0.5, 'ax1', fontsize=16, ha='center')   
Text(0.5, 0.5, 'ax1')
>>> ax2.text(0.5, 0.5, 'ax2', fontsize=16, ha='center')   
Text(0.5, 0.5, 'ax2')
>>> ax3.text(0.5, 0.5, 'ax3', fontsize=16, ha='center')   
Text(0.5, 0.5, 'ax3')
>>> ax4.text(0.5, 0.5, 'ax4', fontsize=16, ha='center')   
Text(0.5, 0.5, 'ax4')
>>> ax5.text(0.5, 0.5, 'ax5', fontsize=16, ha='center')   
Text(0.5, 0.5, 'ax5')
>>> fig.tight_layout()    
>>> plt.show()   

此處使用 Axes 物件的 text() 方法在子圖中央打上名稱, 結果如下 : 




完整程式碼參考 :

測試  : 使用 plt.subplot2grid() 物件排版 [看原始碼]