2022年6月21日 星期二

Python 學習筆記 : 使用 OpenPyXL 操作 EXCEL 試算表 (三)

在前兩篇 OpenPyXL 測試文章中已學會它主要的資料處理功能, 本篇要測試的是它較次要的儲存格的格式設定功能, 主要是應用在大量 xlsx 檔案的自動化處理. 本系列之前的文章參考 :


在此之前先摘要整理前一篇關於工作表操作之指令 :
  • 取得工作表名稱 :
    sheet.title
  • 取得工作表內容之列數與欄數 :
    sheet.max_row
    sheet.max_column
  • 取得儲存格物件及屬性值 :
    cell=sheet.cell(row=2, column=3)        # 呼叫 cell() 方法
    cell=shee['C2']        # 使用 [] 運算子
    cell.row                   # 儲存格列索引
    cell.column             # 儲存格欄索引
    cell.value                # 儲存格內容
    cell.data_type         # 儲存格內容
  • 取得儲存格內容 :
    sheet.cell(row=2, column=3).value
    sheet['C2'].value
  • 將資料寫入儲存格 :
    sheet.cell(row=2, column=3).vaule=123
    sheet.cell(row=2, column=3).value='ok'
    sheet.cell(row=2, column=3).value='=SUM(B2:B5)'
    sheet.cell(row=2, column=3, value=123)
    sheet.cell(row=2, column=3, value='ok')
    sheet.cell(row=2, column=3, value='=SUM(B2:B5)')
    sheet['C2'].value=123
  • 取得列儲存格物件 tuple :
    cells=sheet[5]     # 取得第 5 列所有儲存格 tuple
  • 取得欄儲存格物件 tuple :
    cells=sheet['B'] 
  • 取得指定範圍內的儲存格物件 tuple : 
    cells=sheet['B2':'E5']     # 取得 B2~E5 的全部儲存格物件
    cells=sheet['B2:E5']      # 取得 B2~E5 的全部儲存格物件
  • 取得工作表全部儲存格的產生器 : 
    sheet.rows         # 逐列, 可傳給 list() 或 tuple() 產生全部儲存格
    sheet.columns   # 逐欄, 可傳給 list() 或 tuple() 產生全部儲存格
  • 取得指定範圍內儲存格的產生器 :
    sheet.iter_rows(min_row, max_row, min_col, max_col)   # 逐列
    sheet.iter_cols(min_row, max_row, min_col, max_col)    # 逐欄
  • 插入空白列 :
    sheet.insert_rows(3)               # 在第 3 列前面 (上方) 插入 1 個空列
    sheet.insert_rows(3, 2)           # 在第 3 列前面 (上方) 插入 2 個空列
  • 插入空白欄 : 
    sheet.insert_cols(3)                # 在第 3 欄前面 (左方) 插入 1 個空白欄
    sheet.insert_cols(3, 2)            # 在第 3 欄前面 (左方) 插入 2 個空白欄
  • 刪除指定列或連續列 :
    sheet.delete_rows(3)              # 刪除第 3 列
    sheet.delete_rows(3, 2)          # 從列索引 3 開始往下連續刪除 2 列
  • 刪除指定欄或連續欄 :
    sheet.delete_cols(3)               # 刪除第 3 欄
    sheet.delete_cols(3, 2)           # 從欄索引 3 開始往右連續刪除 2 欄
  • 添加一列資料於工作表尾端 :
    sheet.append(['元小稹', 88, 34, 100, '=SUM(B5:D5)'])   # 串列
    sheet.append({'A':'岑小參', 'B':90, 'C':45, 'D':100, 'E':'=SUM(B6:D6)'})  # 字典
  • 移動一個範圍之儲存格 : 
    sheet.move_range('B2:E6', rows=3, cols=2)        # 向下 3 列向右 2 欄
    sheet.move_range('B2:E6', rows=-3, cols=-2)     # 向上 3 列向左 2 欄
  • 合併一個範圍內之儲存格 :
    sheet.merge_cells('A1:E1')        # 將 'A1:E1' 合併為一格
  • 將被合併的儲存格取消合併 :
    sheet.unmerge_cells('A1:E1')    # 將被合併的 'A1:E1' 範圍內儲存格取消合併
  • 於儲存格中插入圖片 :
    from openpyxl.drawing.image import Image
    sheet.add_image(Image('say_hello.jpg'), 'B9')
  • 凍結儲存格 :
    sheet.freeze_panes='A2'    # 凍結 A2 以左以上之儲存格 (即第一列)
以下測試會使用到下面兩個測試檔案 : 
下載後放在與程式相同之工作目錄下即可. 


7. 儲存格的格式設定 :  

儲存格的格式包含下列項目 : 
  • 字型樣式 (font)
  • 寬度與高度 (width & height)
  • 對齊方式 (alignment)
  • 框線樣式 (border)
  • 格式化條件 (formatting rules)
其中格式化條件用來指定一個條件, 當儲存格內容符合該條件時就改變格式, 例如當股價低於某值時改變儲存格背景色等等. 


(1). 字型樣式設定 :  

使用 Cell 物件的 font 屬性可以設定儲存格的字型, 其值為 openpyxl.styles.Font 物件, 因此使用前必須先匯入 Font 類別 : 

from openpyxl.styles import Font

呼叫 Font 類別建構子 Font() 並傳入如下字型樣式屬性參數即可建立 Font 物件 :


 Font() 參數 說明
 name 字型名稱字串, 例如 'Arial', 'Calibri' (預設), '微軟正黑體' 等
 size 字型大小 (整數, 預設=11 pt)
 color 字型色彩字串 (前景色), 預設 '000000' (黑色)
 bold 是否粗體, True/False (預設 False)
 italic 是否斜體, True/False (預設 False)
 strike 是否有刪除線, True/False (預設 False)


字型樣式的預設值參考 :


例如 : 

>>> import openpyxl as xl     
>>> from openpyxl.styles import Font     
>>> wb=xl.Workbook()           # 建立一個空白工作簿
>>> wb.sheetnames                  # 檢視所有工作表名稱
['Sheet']
>>> sheet=wb['Sheet']             # 取得工作表物件
>>> sheet       
<Worksheet "Sheet">
>>> sheet['A1'].value='Hello World!'             # 寫入 A1 儲存格
>>> sheet['A2'].value='Hello Tony!'               # 寫入 A2 儲存格
>>> sheet['A3'].value='你是在說哈囉嗎?'     # 寫入 A3 儲存格
>>> fontA2=Font(name='Arial', size=14, bold=True, color='0000ff')      
>>> fontA3=Font(name='微軟正黑體', size=12, italic=True, strike=True)       
>>> sheet['A2'].font=fontA2              # 訂定 A2 儲存格字型樣式
>>> sheet['A3'].font=fontA3              # 訂定 A3 儲存格字型樣式
>>> wb.save('styles.xlsx')                   # 工作簿存檔

此例先在 A1, A2, A3 儲存格寫入資料, 然後利用 Font() 建立 A2, A3 儲存格之 Font 物件, 並將它們分別指派給 A2, A3 儲存格物件的 font 屬性 (A1 保持預設樣式), 最後呼叫 wb.save() 將工作簿存成 xlsx 檔. 用 Excel 開啟此檔檢視工作表內容 : 




可見 A1 儲存格為預設字型樣式 (字型 Calibri, 大小 11, 黑色); A2 儲存格字型為 Arial, 大小為 16, 粗體藍色; A3 儲存格字型為微軟正黑體, 大小 12, 斜體有刪除線. 


(2). 列高與欄寬設定 :  

Excel 儲存格的大小是整列或整欄一致的, 所以設定儲存格的大小就是調整列高與欄寬, 這必須透過工作表物件的 row_dimensions 與 column_dimensions 屬性來設定, 其值為 DimensionHolder 物件, 以上面範例中的工作表物件 Sheet 為例 : 

>>> type(sheet.row_dimensions)    
<class 'openpyxl.worksheet.dimensions.DimensionHolder'>
>>> type(sheet.column_dimensions)       
<class 'openpyxl.worksheet.dimensions.DimensionHolder'>

DimensionHolder 物件是列尺寸物件 RowDimensios 與欄尺寸物件 ColumnDimension 的容器, 可用 [] 運算子以列索引 (例如 1, 2, 3,...) 或欄索引 (例如 'A', 'B', 'C', ...) 取得尺寸物件, 例如 :

>>> type(sheet.row_dimensions[1])             # 以整數索引取得列尺寸物件
<class 'openpyxl.worksheet.dimensions.RowDimension'>
>>> type(sheet.column_dimensions['A'])    # 以字串索引取得欄尺寸物件
<class 'openpyxl.worksheet.dimensions.ColumnDimension'>

利用 RowDimension 物件的 height 屬性 (單位是 pt) 即可設定列高 (範圍 0~409 pt); 而 ColumnDimension 物件的 width 屬性 (單位是 pt) 即可設定欄寬 (範圍 0~255 pt), 例如 : 

>>> print(sheet.column_dimensions['A'].width)       
13.0
>>> print(sheet.row_dimensions[1].height)       
None

可見儲存格的欄寬預設是 13pt (72pt 為 1 英吋), 但列高無預設值 (視內容高度而定), 參考 : 


用上面的工作表為例修改 A 欄的欄寬與第 2 列的列高如下 :

>>> sheet.row_dimensions[2].height=40             # 設定第 2 列列高=40pt
>>> sheet.row_dimensions[3].height=50             # 設定第 3 列列高=50pt
>>> sheet.column_dimensions['A'].width=60     # 設定第 1 欄欄寬=60pt
>>> wb.save('styles.xlsx')                                      # 工作簿存檔

用 Excel 開啟結果如下 :  




可見第 1 欄欄寬變寬了, 第 2, 3 列的列高也變大了. 


(3). 儲存格內容對齊設定 :  

儲存格的內容預設是水平靠左對齊, 垂直置中對齊, 但可以利用儲存格物件的 alignment 屬性來設定, 此屬性之值為一個 openpyxl.styles.Alignment 物件, 故須先匯入 Alignment 類別 : 

from openpyxl.styles import Alignment

然後呼叫其建構子 Alignment() 並傳入 vertical 或 horizontal 屬性來建立 Alignment 物件 :

Alignment(vertical=None, horizontal=None)     

其中 vertical 值為字串, 可傳入之值如下 :
  • 'top'
  • 'center'
  • 'bottom'
horizontal 值也是字串, 可傳入之值如下 :
  • 'left'
  • 'center'
  • 'right'
以上面範例中的工作表物件 Sheet 為例 : 

>>> sheet['A2'].alignment        
<openpyxl.styles.alignment.Alignment object>      # Alignment 物件
Parameters:
horizontal=None, vertical=None, textRotation=0, wrapText=None, shrinkToFit=None, indent=0.0, relativeIndent=0.0, justifyLastLine=None, readingOrder=0.0
>>> sheet['A2'].alignment=Alignment(vertical='top', horizontal='center')   
>>> sheet['A3'].alignment=Alignment(vertical='center', horizontal='right')   
>>> wb.save('styles.xlsx')         

此處將上面範例中的 A2 儲存格內容設為垂直靠上對齊, 水平置中對齊; 而 A3 儲存格設定為垂直置中對齊, 水平靠右對齊, 存檔後用 Excel 開啟檔案結果如下 : 




可見 A2 與 A3 儲存格的對齊方式改變了. 


(4). 儲存格邊框設定 :  

Excel 儲存格預設是 1px 的實線, 可以利用儲存格物件的 border 屬性來設定, 其值為一個  openpyxl.styles.Border 物件, 故使用前須匯入此類別來建立物件 :

from openpyxl.styles import Border 

呼叫建構子 Border() 並傳入 left, right, top, bottom 參數即可建立 Border 物件, 語法如下 :

Border(left, right, top, bottom)     

不過儲存格的邊界樣式實際上是透過傳入的四個參數來設定的, 其值為一個 Side 物件, 故還需要從 openpyxl.styles 匯入 Side 類別 :

from openpyxl.styles import Side

呼叫建構子 Side() 並傳入 color 與 style 參數即可建立 Side 物件, 語法如下 :

Side(color, style [, border_style])     

其中 color 為一個 openpyxl.styles.Color 物件, 但也可以直接顏色字串例如 "FF00FF" (與上面 Font 前景色的方式相同, 前面不需 #). 參數 style 為邊界樣式, 可用選項如下 :
  • 'hair'
  • 'thin'
  • 'medium'
  • 'double'
  • 'thick'
  • 'dotted'
  • 'dashed'
  • 'mediumDashed'
  • 'dashdot'
  • 'dashDotDot'
  • 'slantDashDot'
  • 'mediumDashDot'
  • 'mediumDashDotDot'
參考 :


以下以 scores2.xlsx 為例, 將超過 90 分的儲存格 B2 套上藍色框線, 將不及格的 D2 儲存格套上紅色框線, 所以要建立兩個 Border 物件, 例如 : 

>>> from openpyxl.styles import Border   
>>> from openpyxl.styles import Side   
>>> side1=Side(color='FF0000', style='thick')     # 紅色實線
>>> type(side1)    
<class 'openpyxl.styles.borders.Side'>   
>>> side2=Side(color='0000FF', style='mediumDotDot')    # 藍色虛線
>>> type(side2)   
<class 'openpyxl.styles.borders.Side'>  
>>> border1=Border(left=side1, right=side1, top=side1, bottom=side1)   
>>> border2=Border(left=side2, right=side2, top=side2, bottom=side2)    
>>> type(border1)     
<class 'openpyxl.styles.borders.Border'>  
>>> type(border2)   
<class 'openpyxl.styles.borders.Border'>   

此處先建立兩個 Side 物件, 分別給後面建立的兩個 Border 物件使用, 其中 border1 是紅框. 接下來只要將儲存格物件的 border 屬性指定為 Border 物件即可更改齊框線樣式了,  :

>>> wb=xl.load_workbook('scores2.xlsx')    
>>> sheet1=wb['工作表1']       
>>> sheet1['B3'].border=border2        # 藍色虛線 (超過 90 分)
>>> sheet1['D3'].border=border1        # 紅色實線 (不及格)
>>> wb.save('scores2.xlsx')      

開啟 scores2.xlsx 結果如下 :




可見已將不及格的分數 D3 套上紅色實框線, 超過 90 分的 B3 套上藍色虛框線了. 

如果要取消框線設定回復預設值, 只要呼叫 Side() 時傳入參數 border_style=None 建立一個 Side 物件, 並以此物件建立 Border 物件來設定儲存格物件的 border 屬性即可, 例如 :  

>>> side3=Side(border_style=None)    
>>> border3=Border(left=side3, right=side3, top=side3, bottom=side3)   
>>> sheet1['D2'].border=border3  
>>> sheet1['B2'].border=border3    
>>> wb.save('scores2.xlsx')       

以 Excel 開啟 scroes.xlsx 結果如下 : 




可見原本套用在儲存格 B3, D3 的框線樣式都被移除而恢復預設值了. 

(5). 儲存格背景色設定 :  

除了利用邊框樣式來凸顯特定儲存格外, 還可以利用填滿儲存格背景色, 這需要用到 Cell 物件的 fill 屬性, 其值為一個 PatternFill 物件, 故使用前需先從 openpyxl.styles 匯入 PatternFill 類別 :

from openpyxl.styles import PatternFill

呼叫 PatternFill 類別的建構子 PaternFill() 並傳入 bgColor 參數 (Color 物件或色碼字串例如 'FF0000') 即可建立一個 PatternFill 填色物件, 然後將此 PatternFill 物件指配給儲存格物件的 fill 屬性即可, 語法如下 :

PatternFill(start_color, fill_type[, end_color])    

參數 fill_type 為填色類型, 可用選項如下 :
  • solid
  • gray0625
  • gray125
  • lightGray
  • mediumGray
  • darkGray
  • lightGrid
  • darkGrid
  • lightHorizontal
  • darkHorizontal
  • lightVertical
  • darkVertical
  • lightUp
  • darkUp
  • lightDown
  • darkDown
  • lightTrellis
  • darkTrellis
單純填色使用 solid 即可. 參考 :


以上面的 scores2.xlsx 成績單工作表為例, 若要將超過 90 分的儲存格 B3 套上黃色背景色, 以及將不及格的 D3 儲存格套上紅色背景色可以這麼做 :

>>> from openpyxl.styles import PatternFill    
>>> fill_B3=PatternFill(start_color='FFFF00', fill_type='solid')   # 黃色
>>> fill_D3=PatternFill(start_color='FF0000', fill_type='solid')    # 紅色
>>> sheet1['D3'].fill=fill_D3      
>>> sheet1['B3'].fill=fill_B3     
>>> wb.save('scores2.xlsx')       

用 Excel 開啟 scores2.xlsx 結果如下 : 




可見 B3 與 D3 儲存格都分別套上黃色與紅色底色了. 


(6). 格式化條件 :  

格式化條件是依據儲存格的內容來自動調整其格式, 例如股價收盤價與昨日相比若上漲標示為紅色底色; 下跌則標示為綠色底色, 完全依據今收價與昨收價儲存格之內容自動套用底色, 毋須人工指定. 工作表物件有一個 conditional_formatting 屬性, 其值為一個 ConditionalFormattingList 類別, 例如 :

>>> type(sheet1.conditional_formatting)      
<class 'openpyxl.formatting.formatting.ConditionalFormattingList'> 

ConditionalFormattingList 類別有一個靜態方法 add(), 可以不須建立物件直接呼叫並傳入要套用的儲存格區域與格式化條件物件, 這樣即可達成儲存格的格式化條件設定, 語法如下 : 

工作表物件.conditional_formatting.add(range, rule)    

第一參數 range 為要套用格式化條件的儲存格範圍, 第二參數 rule 為一個 Rule 物件, 用來設定執行儲存格格式化之條件與動作, 此物件可呼叫 openpyxl.formatting.rule 的 CellIsRule() 函式來建立, 故使用前須先匯入此函式 :

from openpyxl.formatting.rule import CellIsRule    

呼叫 CellIsRule() 並傳入參數即可建立一個 Rule 物件, 語法如下 :

CellIsRule(operator=None, 
                   formula=None, 
                   stopIfTrue=None, 
                   font=None
                   border=None
                   fill=None) 

其中 font (字型), border (框線), 以及 fill (填滿背景色) 是可套用的格式. 而所謂的條件則是由 operator 與 formula 這兩個參數來設定, operator 是運算子, 其值為字串, 可用的選項如下 :


 operator 參數值 說明
 equal 等於
 notEqual 不等於
 lessThan 小於
 lessThanOrEqual 小於或等於
 greaterThan 大於
 greaterThanOrEqual 大於或等於
 beginsWith 以~開頭
 endsWith 以~結尾
 between 介於~之間
 notBetween 介於~之外
 containsText 包含文字
 notContains 不包含文字


參數 formula 是運算子後面的條件值, 其值為一個串列或元組, 或者是儲存格索引例如 '$B$3', 它可以只有一個元素, 例如用在運算子 'equal' 或 'lessThan' 時; 也有可能包含多個元素, 例如用在 'between' 運算子時. 

參考 :


以上面的成績單為例, 如果要套用格式化條件在超過 90 分的儲存格套用黃底色; 而低於 60 分套用紅底色, 首先要匯入 openpyxl.formatting.rule.CellIsRule 函式來建立 Rule 物件 :

例如 : 

>>> from openpyxl.formatting.rule import CellIsRule      
>>> from openpyxl.styles import PatternFill    
>>> fill1=PatternFill(start_color='FFFF00',  end_color='FFFF00', fill_type='solid')   
>>> fill2=PatternFill(start_color='FF0000', end_color='FF0000', fill_type='solid')    # 紅色
>>> rule1=CellIsRule(operator='lessThan', formula=[60], stopIfTrue=True, fill=fill1)     
>>> rule2=CellIsRule(operator='greaterThanOrEqual', formula=[90], stopIfTrue=True, fill=fill2)     
>>> sheet1.conditional_formatting.add('B3:D7', rule1)   
>>> sheet1.conditional_formatting.add('B3:D7', rule2)       
>>> wb.save('scores2.xlsx')      

此處使用的儲存格格式是填滿底色, 所以先建立兩個 FillPattern 物件, fill1 填黃色, fill2 填紅色, 然後分別傳入 CellIsRule() 函式建立兩個 Rule 物件 rule1 與 rule2, 最後呼叫工作表物件的 conditional_formatting.add() 方法設定成績區域 'B3:D7' 內的儲存格先後套用此兩規則 (誰先誰後皆可), 存檔後用 Excel 開啟檔案結果竟然無效, why?   
 
在官網找到另外一種做法, 改用 openpyxl.formatting.Rule 類別來產生 Rule 物件 :


>>> from openpyxl.formatting import Rule     
>>> from openpyxl.styles.differential import DifferentialStyle    
>>> from openpyxl.styles import Font    
>>> dxf1=DifferentialStyle(font=Font(bold=True), fill=fill1) 
>>> dxf2=DifferentialStyle(font=Font(bold=True), fill=fill2) 
>>> rule1=Rule(type='cellIs', dxf=dxf1, operator='lessThan', formula=[60]) 
>>> rule2=Rule(type='cellIs', dxf=dxf1, operator='greaterThanOrEqual', formula=[90]) 
>>> sheet1.conditional_formatting.add('B3:D7', rule1)   
>>> sheet1.conditional_formatting.add('B3:D7', rule2)       
>>> wb.save('scores2.xlsx')      

但也是無效, 有空再來研究看看. 

參考 : 

價格親民的 Linux 個人電腦 MP510-50

昨天一頭熱對香蕉派 Banana Pi 系列產品做了一番市調, 發現 BPI-M5 與 BPI-M2 Zero 是很不錯的樹莓派代替品, 但今天找到下面這個由中鼎 (客服 02-23623620, 0935-909-821) 開發的 Ubuntu Mate Linux 微型電腦, 大小只有一個巴掌大, 規格跟 BPI-M5 幾乎一樣 (Flash 是四倍 64 GB) :  





仔細看其硬體規格, 發現根本就是 Banana Pi BPI-M5 的客製版, 差別只是內建 Flash 由 16GB 提升為 64GB 以及裝好了 Ubuntu Mate 作業系統而已, 買來即可使用不須做任何設定, PCHome 價格只要 2450 元, 而買一片 Banana Pi BPI-M5 裸版就要 2600 元, 如果只是要拿 Linux 電腦當教學工具 (例如學生因疫情必須居家學習上網連線) 還不如買這台, 不需要買裸板來自行安裝 :  


但若是要做實驗那就得買裸板了. 

2022-06-21 補充 :

昨天 PCHome 商品頁原本顯示 "已售完補貨中", 我今天詢問中鼎, 客服說他查有貨, 說已經催 PCHome 重新上架, 希望我也跟他們反映, 早上寫了 email 給 PCHome (他們的電話根本沒辦法按 9 專人接聽), 結果晚上就上架了, 我馬上下單買一台 : 


折 100 元實付 2350 元. 

報名高雄 Python 社群 Flask 免費線上課程 (3)

今天在臉書 Python 社群看到 6/28 晚上 19:30~20:30 的 Flask (3) 的免費線上課程 : 


我已在 KKTIX 報名參加課程, 到時連線 Google Meet 上課即可 :





我好像之前有報名過 Flask (1), 但卻忘記去上課了. 老師有把之前的課程資料放在 GitHub :


明天起連續三天是 Django 內訓, 月底再上完 Flask, 這樣六月底前就把 Python Web 的學習給一舉解決掉, 不亦快哉! (應該是想得美, 前兩周的 Python + Excel 到現在都還沒結束掉).

香蕉派 Banana Pi M1 A20 開發板

昨天對香蕉派 BPI 開發板做了一點研究, 覺得 BPI-M5 是目前樹莓派市場價格飆漲下很不錯的另類選擇. 這讓我想起 Tim 兄以前好像送給我一塊他在鴻海時開發的香蕉派 (2018 年 9 月, 另外還送我一塊 bpi:bit, 也是他開發的, 超級厲害), 趕緊搜尋零件盒把它找出來, 根據背板上的 A20 晶片, 研判應該是第一代的 Banana Pi M1 A20 開發板, 因為一直都沒時間測試, 所以連防靜電塑膠袋都還沒撕開呢 :




這塊板子很大的特點是提供了 SATA 硬碟插槽 (正下方 HDMI 左邊那個黑色那個), 以及左下角的硬碟電源輸出, 而且板載 MIC 麥克風與紅外線 IR 感測器. 其主要規格如下 : 
  • 處理器 : 全志 A20 雙核Cortex-A7 1 GHz 
  • GPU 圖形處理器 : Mali-400 MP2 
  • 記憶體 : 1GB DDR3 DRAM
  • 外部儲存 : Micro SD (最高可插 64 GB 卡)
  • USB 埠 : USB 2.0 * 2
  • 視訊輸出 : HDMI 
  • 視訊輸入 : CSI
  • 音訊輸出 : 3.5mm 插孔與 HDMI
  • 網路介面 : 1 GbE LAN 
  • 感測器 : 麥克風 & 紅外線 (IR)
  • GPIO : 26 Pins
  • 電源 : USB Type C (2A 以上)
這塊板子光是雙核 CPU 與 1GB DRAM 這兩項, 就比當時主流的 Pi B+ (單核 512 MB DRAM) 還要強悍很多, 參考 : 


教學文件下載 :


主要的 OS 映像檔可從下列網址下載 :

Ubuntu 16.04 映像檔下載 :


Debian 10 映像檔下載 :


Ambian 22.05 映像檔下載 :


2022年6月20日 星期一

市圖預約書目

目前市圖預約中書目 : 
  1. TensorFlow與Keras : Python深度學習應用實務
  2. AI黃金時期正好學 : TensorFlow 2高手有備而來
  3. 一行指令學Python : 用機器學習掌握人工智慧
  4. Python3.x網頁資料擷取與分析特訓教材
  5. Python網路文字探勘入門到上手
  6. Python技術者們練功!
  7. 用Excel學Python資料分析
記下來方便續借與再次預約. 

Banana Pi BPI-M5 開發板

最近樹莓派變成期貨商品似的, 價格持續上漲, 臉書社群一貼出二手 Pi 4B 馬上就被收走, 實在令人傻眼. 早知道去年幫湘芸老師架站時就應該順便自己也買一片, 當時跟飆機器人買 8GB 一片才 2800 元而已, 參考 :


如今 Pi 4B 已飆到近 8 千塊, 讓人買不下去. 

我把目光轉向 Pi 4B 的替代品 : Banana Pi, 目前最新的是 BPI-M5 型號, 露天價格最便宜的大約在 2600 元左右 (Aliexpress 約 73 美元) : 



參考 : 


其中 Aliexpress 73 美元免運折合台幣大約才2200 元不到最划算 (但打五折優惠已過). 

香蕉派 BPI-M5 在硬體上比起 Pi 4 其實並不差, 主要規格如下 :
  • 處理器 : Amlogic S905X3 四核Cortex-A55 2 GHz 
  • GPU 圖形處理器 : Mali-G31 MP2 (4 執行續 650 MHz)
  • 記憶體 : 4GB DDR4 DRAM, 16GB eMMC Flash
  • 外部儲存 : Micro SD (最高可插 256 GB 卡)
  • USB 埠 : USB 3.0 * 4
  • 視訊輸出 : HDMI 2.0
  • 音訊輸出 : 3.5mm 插孔
  • 網路介面 : 1 GbE LAN 
  • 感測器 : 紅外線 (IR)
  • 電源 : USB Type C (3A 以上)
其中內建 16 GB eMMC Flash 我覺得是一大亮點, 這樣作業系統就可以直接安裝在此內建的 Flash 上, 不需要準備一張 Micro SD 卡, 這 16 GB 容量不管是要安裝 Ubuntu, Rasbian, 或 Android 都綽綽有餘. 當然還是可以插一張 MicroSD 卡, 但那就是用來做為存放資料的外部儲存之用. 但缺點是網路僅提供 LAN, 沒有像樹莓派那樣內建 WiFi 與藍芽, 上網需要插一個 WiFi dongle, 或購買 WiFi + BT 擴充板 : 

 
參考 : 


作業系統安裝教學參考 : 


2022-06-20 補充 :

BPI 也有出類似 Pi Zero W 的產品 BPI-M2 Zero, 採用四核處理器比 Pi Zero W 的單核效能強, 而且板帶 IPEX 天線座可外接天線, 目前 Aliexpress 最便宜的是 30.42 美元 :


參考 : 


跑 Benchmark 顯示 BPI-M2 Zero 的效能是 Pi Zero 的四倍, 是 Pi 3A+ 的一半 : 





看起來 BPI-M2 Zero 效能真的比 Pi Zero 要強很多啊! 參考 :


2022年6月19日 星期日

2022 年第 25 周記事

本周主要的心力花在 Python 套件 openpyxl 的測試學習上, 希望一鼓作氣把去年底開的頭拉到底做完, 因為我發現 Excel 很適合做為資料庫的代用品, 可以快速將構想的 Prototype 實作出來, 若需要做成完整的網頁應用程式再移植到資料庫. 另外一個 xlwings 可能先 Hold 一下, 因為還要回頭把正規式進階篇測完 (其實還有一個原因 : 樹莓派上無法使用 xlwings).

因為菁菁說這禮拜想跟我回鄉下, 所以就提早在週六早上就回去了. 但匆匆忙忙竟然忘了把已到貨的露營帳篷帶回去試用, 周末這兩天好熱, 到了晚上夕曬的房間還是熱烘烘, 而二樓頂天台上卻非常涼快, 我打算以後周末回鄉下晚上就睡二樓頂天台的帳篷.

今天下午忙完後去爬獅形頂, 用小米手錶運動版測量繞一圈回來剛好 3 公里 :






走 3 公里路大約花 40~50 分鐘, 每天留些汗真的很不錯. 下周要開始動起來買材料搭建儲能太陽能板的支架了, 估計尺寸跟上回並聯型一樣, 保留一個擴充位置, 看使用情況也許未來還要再加一塊, 600 多瓦應該足夠應付平常夜間照明與緊急用電需求. 

料理實驗 : 實作阿慶師的脆皮燒肉

端午節前我在臉書看到阿慶師的脆皮燒肉作法, 覺得不難做 :





剛好端午節拜祖先的豬肉可以拿來做這道, 但冰箱菜太多, 這幾周終於把親友給的魚消化掉了, 而本周剛好菁菁與水某有一起回鄉下, 就趁這機會實作了這道菜. 







實作結果算是 85 分, 因為皮似乎脆過頭而有點硬, 但有些又真的脆, 可能我家老烤箱溫度比較高, 下次做要設 180 度. 另外我這次醃製時間只有四個小時 (阿慶師說至少要 6 個小時, 最好是放冰箱隔夜), 比較沒那麼入味, 但還是被吃到只剩一塊. 

Chrome 頁籤備份

因為 Chrome 開啟的頁籤實在太多了, 這樣會吃掉很多記憶體, 暫時將目前沒時間細看, 但具有參考價值者先記錄下來後關掉 : 


2022年6月18日 星期六

市圖還書 4 本

本周市圖有四本書被預約要還 :
因目前正在專心學習 Python+Excel+Pandas+爬蟲, 故 No.1~3 的機器學習暫緩也好, 尤其 PyTorch 我看是排在 TF2 之後為宜. No.4 是在鄉下的分館偶然在書架上看到的, 稍微翻閱一下發現房市水還真的很深啊! 買房前值得一讀.