2018年1月31日 星期三

購買三洋全免持話機

家裡的小話機近來常因接觸不良一接就斷線, 在露天找到三洋全免持話機 TEL-011, 這樣講電話時就不用手拿話機, 可以一邊講一邊打電腦很方便 :

全新 SANLUX 三洋 TEL-011 TEL011 全免持對講來電顯示電話機 $488




此款話機在 Yahoo 等賣 675 以上. 老闆說只剩下 9 個庫存新品, 賣完就沒了.

向博客來買 Python 深度學習

博客來的生日折價券 50 元今日到期, 本想買 "R資料科學", 但幾經考慮還是買 "Python深度學習" 這本, 因為此書內容牽涉較廣, 而前者內容較深 :




扣除折價券大約是七折優惠.

R 語言學習筆記 (四) : 因子

進入 2018 年後工作項目與同事交換, 得重新學習與整理 SOP (我是 SOP 控啊),  R 語言的學習速度就慢下來了, 只能撿夾縫中的五分鐘學習, 以下是最近對因子物件的測試紀錄. 此前的筆記如下 :

R 語言安裝
在樹莓派上安裝 R 語言
R 語言學習筆記 (一) : 基本語法與向量
R 語言學習筆記 (二) : 矩陣
R 語言學習筆記 (三) : 陣列

因子是 R 語言中用來儲存類型變數 (Categorical) 的資料結構. 統計學將變數區分為如下四種 :

 類型 說明 範例
 名義變數 只區別名稱, 無順序之分, 無法排序的變數 男女, 優劣, 晴陰雨
 順序變數 有排序意義的變數 名次, 歌曲排行榜
 離散變數 以整數為計數單位的變數, 其差距有意義 每周外食次數
 連續變數 可連續取值之變數 身高, 體重

其中名義型變數與順序型變數具有可分類或可分級概念, 又稱為類型資料 (Categorical Data), 在 R 語言是以 factor (因子, 等級) 資料結構來儲存, 其中可排序的稱為有序因子 (ordered factor). 因子在 R 語言中是一種特殊的向量類型, 其內容之資料類型是一組表示名義或順序屬性的數值與字串, 例如 "男", "女" 或 1, 2, 3 等.


一. 建立因子物件的方法 : 

1. 呼叫 factor() 函數 : 

factor() 的 API 如下 :

factor(x = character(), levels, labels = levels,
       exclude = NA, ordered = is.ordered(x), nmax = NA)

其中 :

x=向量 (通常是表示名義變數的字串或數值向量)
levels=設定之因子等級  (通常是字串或數值向量)
labels=因子數值加上標籤 (預設為 levels)
exclude=要排除的因子等級 (預設 NA 不排除)
ordered=因子是有序或無序 (預設 FALSE 無序)
nmax=因子等級最大值 (預設 NA 無最大值)

其中最主要的是前兩個參數, 即向量 x 與因子 levels (等級).

傳入向量 x, factor() 可將其轉換成因子. 例如 :

> grade1 <- c("A","B","A","C","B")
> fac1 <- factor(grade1)
> fac1
[1] A B A C B
Levels: A B C         #因子等級為不重複之元素 (沒有雙引號)

可見顯示因子變數時, 不僅會顯示內容, 還會顯示這些元素的 "等級 (Level)", 即不重複的部分. 這些等級 (level) 預設是以字母順序排列的, 因子與向量不同之處是因子會將元素分群 (grouping), 相同的元素在一群就是一個因子, 因子用來儲存元素的類別 (Category).

用 class() 檢查因子變數可知其資料結構為 factor, 用 mode() 檢查其資料型態卻是 numeric, 這表示 Levels 的資料型態是數值, 雖然 Levels 看起來像是字串, 但實際上 R 語言內部是用整數索引來代表元素之值與等級, 可用 as.numeric() 或 as.integer() 函數得知.

> class(grade1)
[1] "character"
> mode(grade1)    #字串向量元素資料型態為 character
[1] "character"
> class(fac1)         #因子之資料結構為 factor
[1] "factor"
> mode(fac1)
[1] "numeric"            #因子等級其實是用整數索引儲存的

呼叫 str() 會顯示因子變數之結構, 可印證因子元素都是以整數索引儲存 :

> fac1 <- factor(c("A","B","A","C","B"))
> str(fac1)
 Factor w/ 3 levels "A","B","C": 1 2 1 3 2 

可見等級 A, B, C 分別以 1, 2, 3 儲存, 因此因子變數之元素在內部實際上是儲存索引值 1 2 1 3 2.

由於因子變數之值通常是數值, 字串, 或布林值, 因此可呼叫 as.charactor(), as.numeric(), 與 as.logical() 將因子變數分別轉成字串向量, 數值向量, 或布林向量, 例如 :

> fac1 <- factor(c("A","B","A","C","B"))
> fac1
[1] A B A C B
Levels: A B C
> as.character(fac1)
[1] "A" "B" "A" "C" "B"
> as.integer(fac1)
[1] 1 2 1 3 2
> as.logical(fac1)
[1] NA NA NA NA NA     #因 "A", "B", "C" 不是布林值
> as.logical(factor(c("TRUE","FALSE")))
[1]  TRUE FALSE

不過在 "R 語言 : 邁向 Big Data 之路 (上奇, 洪錦魁)" 一書中提到, 由於因子變數之元素值在 R 語言內部以 1, 2, 3, ... 等整數儲存, 對於元素為數字之因子變數而言, 使用 as.integer() 轉換時可能會有計算上的問題, 例如下列成績資料 :

> scores <- factor(c(78,99,67,56,100,23))
> scores
[1] 78  99  67  56  100 23
Levels: 23 56 67 78 99 100
> str(scores)
 Factor w/ 6 levels "23","56","67",..: 4 5 3 2 6 1
> as.numeric(scores) 
[1] 4 5 3 2 6 1 

可見將因子用 as.numeric() 轉回數值向量時, 傳回的是因子變數內部代表元素的 1, 2, 3, 4, 5 索引值, 而非原始的成績. 這時可先呼叫 as.character() 再呼叫 as.numeric 來避免運算上的錯誤, 因為 as.charactor() 會傳回因子變數元素值之字串向量, 而非元素索引之字串向量 :

> as.character(scores)                        #as.character() 會傳回元素之字串向量
[1] "78"  "99"  "67"  "56"  "100" "23"
> as.numeric(as.character(scores))    #先呼叫 as.character()  轉成字串向量
[1]  78  99  67  56 100  23

可見傳回的是原始成績之數值向量而不是 1, 2, 3 ... 的索引了.

factor() 函數的第二參數 levels 用來列舉因子變數有哪些的等級. 雖然 factor() 會從元素的分群中自動找出因子的等級, 但當收集的數據不完整時, 等級 (Levels) 就會有缺漏, 例如 :

> seasons <-c("Spring", "Winter", "Spring", "Summer")
> fac2 <- factor(seasons)
> fac2
[1] Spring  Winter Spring  Summer
Levels: Spring Summer Winter              #等級按照字母順序排列

可見由於原始資料缺了 "Fall", 因此也會使等級缺了 "Fall" 這一項, 這時可利用 levels 參數指定完整的等級有哪些, 且等級會按照 levels 參數指定之順序排列 :

> fac3 <- factor(seasons, levels=c("Winter","Fall","Summer","Spring"))
> fac3
[1] Spring  Winter Spring  Summer
Levels: Winter Fall Summer Spring        #等級按照 levels 參數指定之順序排列

注意, 以 levels 指定等級時, 顯示變數時會按照所指定之順序排列而非預設之按字母順序. 注意, 若指定的 levels 參數不是完整的因子序列, 則顯示因子變數時, 在 levels 中找不到等級之元素會顯示 NA, 例如 :

> ordered(c("A","B","A","C","B"),levels=c("C","B"))
[1] <NA> B    <NA> C    B 
Levels: C < B

呼叫 levels() 函數會傳回一個字串向量, 其元素為因子變數的全部等級. 注意, 即使等級是數值, levels() 也是傳回字串向量, 例如 :

> fac4 <- factor(c("A","B","B","C"))    #元素為字串
> fac4
[1] A B B C
Levels: A B C                                #沒有雙引號
> fac5 <- factor(c(1,2,2,3))   #元素為數值
> fac5
[1] 1 2 2 3
Levels: 1 2 3                                  #沒有雙引號
> levels(fac4)
[1] "A" "B" "C"
> levels(fac5)
[1] "1" "2" "3"                               #有雙引號 : levels() 一律傳回字串向量

函數 nlevels() 則會傳回因子有幾個等級, 例如 :

> grade1 <- c("A","B","A","C","B")
> fac1 <- factor(grade1)
> fac1
[1] A B A C B
Levels: A B C
nlevels(fac1)      #傳回因子等級數目
[1] 3                            #含有 A, B, C 三個等級

factor() 函數預設使用元素本身作為等級之值, 參數 labels 可搭配 levels 參數來變更因子的顯示標籤, 例如以 "E", "W", "S", "N" 縮寫來代替 "EAST", "WEST", "SOUTH", "NORTH" :

> directions <- c("EAST", "WEST", "SOUTH", "NORTH", "WEST", "NORTH")
> fac6 <- factor(directions,levels=c("EAST","WEST","SOUTH","NORTH"),labels=c("E", "W", "S", "N"))
> fac6
[1] E W S N W N   
Levels: E W S N    

可見不論元素或等級之值都被對應之 label 所取代了. 如果 labels 不是對應 levels 的字串向量, 而是單一字串, 則會以該字串冠上元素的等級數值作為新的元素與等級, 例如 :

>directions <- c("EAST", "WEST", "SOUTH", "NORTH", "WEST", "NORTH")
> fac7 <- factor(directions)
> str(fac7)
 Factor w/ 4 levels "EAST","NORTH",..: 1 4 3 2 4 2
> fac8 <- factor(directions, labels="d")          #會冠在等級數值前面
> str(fac8)
 Factor w/ 4 levels "d1","d2","d3",..: 1 4 3 2 4 2 
> fac8
[1] d1 d4 d3 d2 d4 d2      #元素被改掉了
Levels: d1 d2 d3 d4         #等級也被改掉了

呼叫 tables() 函數會傳回一個 table 物件, 顯示各個等級的次數統計, 例如 :

> fac1 <- factor(c("A","B","A","C","B"))
> table(fac1)
fac1
A B C
2 2 1                                #levels 的等級統計
> class(table(fac1))
[1] "table"                       #傳回 table 物件
> str(table(fac1))
 'table' int [1:3(1d)] 2 2 1
 - attr(*, "dimnames")=List of 1
  ..$ fac1: chr [1:3] "A" "B" "C"

傳回的 table 物件可以用索引存取, 例如 :

> tab1 <- table(fac1)
> tab1[1]       #以索引存取 table 物件
A
2
> tab1[1] == 2
   A
TRUE

factor() 的 ordered 參數預設為 FALSE, 表示預設建立無序因子, 若設為 TRUE 表示所建立的因子是有序的, 例如 : 

> fac1 <- factor(c("A","B","B","C"))
> fac1
[1] A B B C
Levels: A B C
> fac7 <- factor(c("A","B","B","C"), ordered=TRUE)    #有序因子
> fac7
[1] A B B C
Levels: A < B < C      #等級是有順序的

可見有序因子的等級 (levels) 是照字母順序排序的. 


2. 呼叫 as.factor() : 

除了用 factor() 建立因子外, 也可以用 as.factor() 函數將向量轉成因子, 例如 :

> grade1 <- c("A","B","A","C","B")
> fac1 <- factor(grade1)
> fac1
[1] A B A C B
Levels: A B C
> fac2 <- as.factor(grade1)
> fac2
[1] A B A C B
Levels: A B C
> class(fac2)
[1] "factor"
> identical(fac1, fac2)    #比較是否為相同物件
[1] TRUE

用 identical() 函數比較可知, 用 factor() 與 as.factor() 所建立之因子物件是雷同的 (結構與內容都一樣). 由於因子的元素通常為字串, 數值, 或布林, 因此可以用 as.character() 將因子物件轉型為字串向量, 用 as.integer() 與 as.numeric() 函數將因子物件轉為數值向量, 或用 as.logical() 轉成布林向量, 例如 :

> grade2 <- as.character(fac1)
> grade2
[1] "A" "B" "A" "C" "B"
> identical(grade1, grade2)
[1] TRUE
> grade3 <- as.numeric(fac1)
> grade3
[1] 1 2 1 3 2
> grade4 <- as.integer(fac1)
> grade4
[1] 1 2 1 3 2

可見因子的等級 A, B, C 分別對應到 1, 2, 3 這三個整數, 由 mode() 可知等級實際上在 R 語言內部是以整數儲存.


2. 呼叫 ordered() 建立有序因子 (ordered factor) : 

有序的類別型資料 (即統計學中的順序變數) 可用有序因子處理, 此函數 API 如下 :

ordered(x, ...)

其中參數 x 為原生向量 (數值, 字串, 布林等), 其餘參數 ... 與 factor() 參數一樣. 例如 :

> ordered(c("A","B","A","C","B"))
[1] A B A C B
Levels: A < B < C         #等級按字母順序升序排列
> ordered(c("A","B","A","C","B"),levels=c("C","B","A"))    #指定等級序列
[1] A B A C B
Levels: C < B < A         #按 levels 參數指定之等級排序       
> ordered(c(1,2,1,3,2))
[1] 1 2 1 3 2
Levels: 1 < 2 < 3                 
> ordered(c(TRUE,FALSE,TRUE,TRUE,FALSE))
[1] TRUE  FALSE TRUE  TRUE  FALSE
Levels: FALSE < TRUE         

可見有序因子的等級與一般因子不同之處在於多了方向標誌 "<", 若沒有用 levels 參數指定等級順序, 預設為按字母排列. 呼叫 class() 可以看出有序因子多了 "ordered" :

> class(ordered(c(1,2,1,3,2)))     
[1] "ordered" "factor"                     #物件類型為有序因子
> class(factor(c(1,2,1,3,2)))
[1] "factor"                                      #物件類型為一般因子

事實上, 這與呼叫 factor() 時使用 ordered=TRUE 參數建立之因子變數是完全一樣的, 例如 :

> fac3 <- ordered(c("A","B","A","C","B"))
> fac3
[1] A B A C B
Levels: A < B < C
> fac4 <- factor(c("A","B","A","C","B"), ordered=TRUE)
> fac4
[1] A B A C B
Levels: A < B < C
> identical(fac3, fac4)
[1] TRUE


二. 存取因子變數 :

因子變數其實就是添加了等級屬性的向量物件, 存取元素之方法與向量一樣都是使用索引 [], 例如 :

> fac1 <- factor(c("A","B","A","C","B"))
> fac1
[1] A B A C B
Levels: A B C
> fac1[1]
[1] A
Levels: A B C
> fac1[5]
[1] B
Levels: A B C
> fac1[2:4]
[1] B A C
Levels: A B C

更改因子變數之元素值, 所賦予之值必須在等級 (levels) 範圍內, 否則會出現錯誤, 例如 :

> fac1[1] <- c("K")       #以 "K" 替換第一元素失敗 : 不在等級範圍內
Warning message:
In `[<-.factor`(`*tmp*`, 1, value = "K") :
  invalid factor level, NA generated
> fac1[1] <- c("C")        #第一元素改為 "C"
> fac1
[1] C B A C B
Levels: A B C

函數 levels() 會將因子之等級以向量傳回, 因此也可用 [] 索引來存取因子等級 :

> fac1 <- factor(c("A","B","A","C","B"))
levels(fac1)                        #傳回因子變數之全部等級
[1] "A" "B" "C"
> class(levels(fac1))             #levels() 傳回字串向量
[1] "character"
> levels(fac1)[1]                   #顯示指定之等級分量
[1] "A"
> levels(fac1)[2]
[1] "B"
> levels(fac1)[3]
[1] "C"
> levels(fac1)[1] <- c("D")    #改變因子等級
> fac1
[1] D B D C B                #等級 A 被改成 D 了
Levels: D B C


三. 因子常用函數 :

因子變數常用函數整理如下表 :

 函數 說明
 factor(x, levels, ...) 將向量 x 轉型為因子物件
 gl(n, k) 建立一個含有 k 個等級
 str(x) 顯示物件結構與內容
 length(x) 顯示陣列元素個數
 dim(x) 顯示物件 (矩陣, 陣列, 資料框) 維度
 is.factor(x) 檢查是否為因子類型
 as.factor(x) 將向量轉型為因子類型
 as.numeric(x) 將因子轉型為數值類型
 as.integer(x) 將因子轉型為整數類型
 as.charactor(x) 將因子轉型為字串類型
 identical(x, y) 檢查兩個物件 x, y 是否為相同物件
 levels(x) 傳回因子 x 之水平向量
 nlevels(x) 傳回因子 x 之水平數量


2018年1月30日 星期二

2018年1月28日 星期日

2018 年第 4 周記事

忽然間 2018 的第一個月就要結束, 這一周我更忙碌了, 白天可說從上班忙到接近下班, 所以也沒多少空閒時間學習, 全力撰寫新工作的作業手冊, 我希望在第一季結束前能完成.

從去年底 12/9 上到昨日 1/27 共 45 小時的太陽光電訓練班終於結束了, 這 8 個周六是我喝咖啡最兇的時候 (一天三杯), 因為沒時間睡午覺, 都靠早上的咖啡撐住下午的眼皮. 雖然不參加檢定, 但我自認是最認真學習, 最常舉手發問的.

以前的舊底片這半年來請三大幫我轉檔, 剩下最後六捲了, 每次拿回底片與光碟, 檢視這些往日雲煙, 心裡想 : 這就是那些已經過去的人生嗎? 人生到底是甚麼? 雖然已屆知天命之年, 我還是參不透.

早上去市集前在酒櫥中找到我的電機技師執照, 挖咧, 到今年已整整三十年! 因為沒有護貝, 表面已經有點泛黃, 想帶回高雄處理. 我在網路上找到一篇讀機械的努力了五年考上電機技師的文章, 作者的精神令我敬佩 :

# 關於電機技師考試的回憶錄

作者的感言中有一點我非常同意, 那就是學統計真的很有用!

2018年1月27日 星期六

太陽光電設置班第八課 (結訓)

近兩個月的太陽光電課今日結訓, 今天只有早上半天課, 老師把乙級技術士檢定術科程序從頭講一遍, 特別叮嚀幾個無關技術, 但連老師傅都常因此出局的關鍵因素 :
  1. 報備送電後必須戴上絕緣手套避免觸電
  2. 注意不要被箱體或模組刮傷, 考試中受傷就出局
  3. 線必須放入線槽, 過長塞不下才可以放槽外, 完全沒放入線槽就出局
講完後上頂樓, 助教已將考試當天的現場情況布置好, 讓要考的同學熟悉一下考前現場狀態. 高雄市太陽能設備裝修職業工會陳理事長這時也上來頂樓與大家寒暄並拍結訓照. :




經過 45 小時課程終於領到結訓證書了, 我可是全勤喔! 聽陳理事長 (也是高師大校友) 說才知道太陽光電職業工會目前全國只有高雄市一家而已, 希望大家踴躍參與, 工會的低廉職安保險可以提供從業人員多一層保障, 若有同學想參與實習或實務工作, 工會也有很多資源可媒合. 雖然我只是來學習長見識, 但認識了許多朋友也是一種技術學習外的收穫.

智慧家庭實驗室與 i 聯網社團

今天在找要買的書時於 "IoT物聯網無限商機:產業概論x 實務應用" 這本書的簡介中看到作者成立的兩個物聯網臉書社團 :

智慧家庭實驗室
# i 聯網

我申請加入時發現另一位臉書好友 Lanma Chiu (Zenbo 推廣者) 也在裡面了.

2018年1月26日 星期五

購買Python資料科學與機器學習書籍

金石堂還有三張 50 元禮券, 今天用兩張買了下面兩本歐萊禮的書 :


Source : 金石堂

Source : 金石堂




這樣金石堂就剩下一張 70 元禮券 (2/2 到期, 須滿 700 元才能用). 考慮買下列擇二 :

Prototyping Lab 第2版:「邊做邊學」,Arduino的運用實例 79 折 537 元
打造Web物聯網|使用Node.js與Raspberry Pi  7 折 434 元
改變世界的力量:臺灣物聯網大商機(第二版) 79 折 332 元
IoT物聯網無限商機:產業概論x 實務應用 79 折 379 元
Raspberry Pi超炫專案與完全實戰(第二版) 79 折 458 元
高效率資料分析:使用Python 79 折 458 元 
圖解資料結構使用Python 85 折 425 元 (明儀買)
Data Science from Scratch中文版:用Python學資料科學 $580 七九折 $458

而博客來的 50 元生日禮券 (1/31 到期) 考慮買下列擇一 :

R資料科學 (博客來) 79 折 $616
Python深度學習 (博客來) 78 折 $484
TensorFlow+Keras深度學習人工智慧實務應用  (博客來) 79 折 $466
機器學習:Python實踐 (簡體) 354 元

其他書單 :

演算法技術手冊 第二版
Data Science from Scratch中文版:用Python學資料科學
TensorFlow+Keras 深度學習人工智慧實務應用 $502
Web安全之機器學習入門
AI:人工智能的本質與未來
Python 資料運算與分析實戰 (2/5 上市)

2018年1月23日 星期二

2018 年第 3 周記事

本周二哥學校段考結束, 週六跟我一起回鄉下. 新工作還是很忙, 幾乎從早忙到下班, 可能要一兩個月才會漸漸上手, 萬事總是起頭難啊! 但只要累積足夠的 SOP, 以後做事就會很順, 也打算將部分耗時耗工的項目寫程式來予以自動化.

由於工作忙, 所以大部分研究都停頓下來. 停頓也不全是壞事, 可以想想下一步該聚焦哪裡, 我的毛病就是興趣太多, 喜新厭舊, 更糟的是常全線開火, 方向失焦. 但眼下最重要的應該是陪菁菁準備會考, 以及應付二哥準備 APCS 可能遇到的問題. 

太陽光電設置班第七課 (補記)

前天 (週六) 是太陽光電班全日最後一天, 早上老師介紹抄表後再到樓上練習靜態檢查, 要注意的事項例如電壓比較不受日照溫度影響, 但電流則與日照成正比, 所以抄表時短路電流與日照強度最好同時記錄, 若間隔太久會數值不匹配遭到監評的質疑. 第一站主要是高阻計量絕緣電阻 (正常值大約 1000M 左右) 以及接地線的電阻 (正常是近乎 0 歐姆), 第二站則要注意送電的順序, 例如獨立型要先送蓄電池再送模組的電, 最後再接上負載, 直流負載約 3 歐姆, 交流負載約 40 歐姆, 不要接反了 :




下午老師講完表頭 ID 設置方式, 然後到隔壁教室模擬盤練習設定, 不過要參加技術士檢定的同學都在補強 PVC 管烤管彎管技術, 我只是上去看一看就下來讀 Python 的書了, 沒參加檢定就沒有動力去練實作啊! 不過我實在沒時間考照, 事實上也用不到. 不過聽發哥與水龍兄所言, 我的電機技師執照考上了這麼多年又沒用到還真是可惜, 有空要找出來才對.

2018年1月21日 星期日

樹莓派安裝 TeamViewer

雖然透過動態 IP 異動回報機制, 我已經能夠利用 VNC Viewer 經由 Internet 遠端操控鄉下的 Pi 3, 但在安博盒子成功安裝 TeamViewer 後, 我想是否也可以在樹莓派上安裝 TeamViewer ? 可以的. 我參考下面這篇完成了這項測試 :

TeamViewer on Raspberry Pi

首先開啟樹莓派瀏覽器, 連線 TeamViewer 下載頁 :

https://www.teamviewer.com/en/download/linux/#downloadAdditionalDownloads

拉到最底下的 "TeamViewer Host for Raspberry Pi", 按 "Download Host" 按鈕下載 deb 安裝檔 :





點選網頁底下的下載檔或開啟 "Accessaries/File Manager", 可在 home/pi/Downloads 下找到下載之 deb 檔, 點按執行安裝, 須先輸入樹莓派帳密 :





安裝完畢後可在桌面右上角或 "Internet" 看到 TeamViewer 13 Host :




執行 TeamViewer Host 後, 按底下 Grant easy access 鈕, 登入 TeamViewer 用戶帳密 (須先註冊), 再按 Assign, 這時會發送一封認證信到郵箱 :




開啟認證信, 點信中的 "Add to trusted device" 超連結, 會開啟我的 TeamViewer 控制台, 按底下的 "新增裝置" 鈕就會將樹莓派加入裝置群組中, 這樣以後就不用記這台裝置的 ID, 只要登入 TeamViewer 帳號就可以從群組中直接點選連線 :





接下來須設定 TeamViewer Host 的密碼, 按 TeamViewer 右上方的設定鈕 :




在 "General" 頁籤可設定此裝置之顯示名稱  :




在 "Security" 頁籤可設定固定密碼, 因為 Host 是用在無人值守的裝置, 使用隨機密碼沒意義 (沒有人可來看隨機密碼) :




但為了安全起見, 可按底下的 "Configure" 鈕設定允入白名單, 輸入允許連接進來的 ID 後, 按 + 就會加入底下的允入清單中 :




經過以上設定後, 從外網允入之電腦或手機等裝置便可透過 TeamViewer 連線此樹莓派了 :




其實 TeamViewer 跟 VNC Cloud 功能類似, 就是透過中央伺服器來連線, 無需知道對方的公網 IP, 對遠端維護控制而言實在很方便.

參考 :

How to install TeamViewer Host for Linux

如何刪除 TeamViewer 不再連線的設備

昨晚回到鄉下也依樣畫葫蘆, 給安博盒子安裝 Android 啟動管理項 App, 順便安裝 TeamViewer.  TeamViewer 程式右邊有登入畫面, 我記得以前有註冊過帳號, 登入後會自動列出以前連線過的設備, 例如 :




但其實這些都是好幾年前的電腦, 都已經汰換了, 該怎麼刪除呢? 很簡單, 只要點選該設備, 按右方的下箭頭, 再按齒輪右方的小三角形, 選擇 "刪除" 即可 :




選擇 "屬性" 會顯示此設備之連線屬性, 可以更改其別名與密碼 (連線時請對方告知後修改) :




也可以在 TeamViewer 網站登入後管理所連線的設備, 參考 :

https://login.teamviewer.com

2018年1月18日 星期四

視覺化資料探勘工具 RapidMiner

最近在亞馬遜找到下面這本 Packt 出版的書, 介紹視覺化資料分析工具 RapidMiner, 此軟體可說是機器學習方面的 Visual Studio :

# Packt : Exploring Data with RapidMiner
# Amazon : Exploring Data with RapidMiner

RapidMiner 由德國資料科學家 Ingo Mierswa 所創立, 主力產品為整合式資料科學與機器學習平台 RapidMiner, 具有集群, 迴歸, 支持向量機等超過 1500 種機器學習功能與模型, 目前總部在美國波士頓, 並在英國, 德國, 匈牙利設有分公司, 參考 :

https://rapidminer.com

RapidMiner 的台灣代理為昊青, 有提供免費 Community 版本, 但資料限制為 10000 筆 :

https://rapidminer.com/pricing/




官方使用手冊可在下列網址下載 :

# https://docs.rapidminer.com/downloads/DataMiningForTheMasses.pdf

參考 :

機器學習工具介紹 Demos for Machine Learning Tools

購買樂活樂捷

之前為爸買的關節保養品 "好關鍵" 吃完了, 由於效果似乎還好, 所以這次改買台視長春月刊的 "樂活樂捷", 可在台視真享購購物平台訂購 :




本想買 3 盒試試看, 但試算後覺得還是買 10 盒送兩盒的比較划算 (平均每盒差 275), 而且使用期間長一些再來評估功效也較合理 :

健康迎18↘下單現折 【常春樂活】靈活樂捷膠囊(60顆/盒,3盒) $4950

平均每盒 1650

健康迎18↘下單現折 【常春樂活】靈活樂捷膠囊(60顆/盒,10盒) 贈送2盒,共12盒 $16500

平均每盒 1375




因為是特價, 右邊那個千元折價券不適用.

2018年1月17日 星期三

利用 Teamviewer 進行遠端控制與傳送檔案

TeamViewer 這軟體很好用, 幾年前我就已經用來幫博士班學姊遠端檢查她們用我寫的的大量語音處理套件時出現的錯誤, 這樣就不必另外約時間帶著厚重筆電見面, 節省人力物力功不可沒. 前天菁菁要複製 mp3 音樂時發現她手機與電腦 USB 連線時抓不到, 改用藍芽偏偏買來沒用過的接收器不賞臉, 讓我想起 TeamViewer 或許可以派上用場.

上網搜尋發現果真 TeamViewer 已經支援 Android, 亦即 TeamViewer 不僅可以 PC 遠端控制 PC, 也可以 PC 與 Android 手機互相控制. 只要上 Google Play 下載安裝 "TeamViewer 遠端控制版本" 或 "TeamViewer Quick Support" 即可, 前者可操控遠端或被遠端操控, 而後者 QS 則只用在被操控端.




在電腦端則是直接安裝 TeamViewer 遠端控制版本即可, 啟動後只要輸入對方 TeamViewer 的 ID 就可以連線了.

家裡的安博盒子也是 Android, 所以也是可以安裝, 我剛好要解決安博開機後要按好兩三次按鈕才能進去 UBTV 問題, 所以參考下列文章下載了 Android 啟動管理項 App (APK 檔) :

開機自動執行直播UBTV

此 APK 檔剛好可用 TeamViewer 將 APK 檔傳過去安裝, 以下是 PC 端 TeamViewer  畫面 :






傳檔安裝後設定啟動時執行 UBTV, 確實會自動進入直播畫面. 參考 :

unblock tv box autorun ubtv app when start
安博盒子電視開機即ubtv第四台電視節目如何設定
安博盒子3 & 4 開機直接進入直播教學- 明穎資訊

我的教師節卡片

早上在整理爆滿的辦公室抽屜時找到一張用鉛筆寫的卡片, 原來是以前姊姊小學四年級時的導師展穗老師請班上同學寫給我的教師節感恩卡, 感謝我在晨光時間陪他們度過那一段時光 :




看完讓我的思緒瞬間穿越回到九年前的 2009 年 ...  在那之前我花了非常多時間融入了小狐狸們的教學活動, 參加戶外教學, 晨光時間, 運動會, 園遊會, 座談會, ... 等等, 是我過去十年中最快樂的時光, 好像我又過了一次童年似的.

但 2009 年的夏天母親得到淋巴癌之後, 我就沒這麼多時間參加她們的學校活動了, 特別是二哥班上大概只去過兩三次晨光, 菁菁班上只在小一時去講了一次林海音的蔡家老屋鬼故事而已. 菁菁有一天跟我說遇到以前低年級的同班同學, 他們對蔡家老屋還印象深刻哩!

2018 年第 2 周記事

很快新年的第一周過去了, 本周繼續花時間在新工作的 SOP 整理上, 有了 SOP 心裡就會比較踏實, 就像我所有的學習都會盡量留下紀錄一樣, 下次用到時就有案可稽.

這個周末沒有訪客, 原以為會有比較多的時間做事, 實際上原本想整理的書房卻動也沒動, 帶回去的 R 語言書也沒時間看, 僅僅完成鄉下 Win 10 電腦的升版備份而已. 想做的事很多, 但能完成的卻很有限.

週日傍晚拿捲尺上頂樓丈量鐵皮屋頂尺寸, 估計向南的那一面應該夠安裝 6 塊太陽能板, 至少可達 2~3KW 容量, 自用應該綽綽有餘. 

週日在鄉下市圖分館挖到三本好書 :

1. Linux Shell 程式設計實力養成


Source : 金石堂



Source : 誠品





Source : Taaze


Linux Shell 這本已出第二版, 市圖只能借到第一版, 但高應大圖書館有, 已向母校調借. 

2018年1月16日 星期二

一本探討 Arduino 中斷的好書

最近找到一本德國人寫的 Arduino 好書 (英文版), 專門探討如何善用中斷來增進 Arduino 專案程式的效能, 只有薄薄 70 幾頁, 但技法卻非常寶貴 :

Arduino Interrupts: Speed up your Arduino to be responsive to events


Source : Amazon


這可不是一般 Arduino ABC 的書, 而是深入探討以 ATMEG328 為基礎的 Arduino 板子如 UNO, Mini, Micro 等之中斷運作, 包括 Watchdog 以及 AVR 晶片內部暫存器之存取控制, 屬於進階級練功專用, 值得花點時間好好研究.

2018年1月14日 星期日

Windows 安裝 Python 機器學習工具

這兩天在讀剛從金石堂買來的 "Deep Learning from scratch (歐萊禮出版, 齋藤康毅著)", 對 Python 的興趣又燃起來了. 自從 MicroPython 告一段落後已四個月沒碰 Python 了. 這一個月分心去學太陽光電安裝, 隨著課程進入尾聲, 該回到 Python 機器學習的學習軌道了.


Source : 金石堂


這本書是從歐萊禮日文原文書 "ゼロから作る Deep Learning" 翻譯來的, 非常適合 ML 初學者 (日本人不愧是知識整理的佼佼者), 我覺得是所有 ML 入門書中寫得最好的一本, 我才看一小時就已攻到第三章. 因作者強調要從基礎學起才能真正了解機器學習奧義, 因此整本書只用了 Numpy 與 Matplolib 這兩個套件而已. 此書範例可從 Github 下載 :

# https://github.com/oreilly-japan/deep-learning-from-scratch


昨晚回到鄉下想測試 matplotlib, 發現我的 Win10 竟然沒有安裝 Python 機器學習套件, 於是參考之前在樹莓派安裝的步驟, 在命令列下達五個指令很快即安裝完畢 :
  1. pip3 install numpy (直接安裝 scipy 就會同時安裝 Numpy)
  2. pip3 install scipy
  3. pip3 install matplotlib
  4. pip3 install pandas
  5. pip3 install scikit-learn
參考 :

在 Windows 中安裝 Python 機器學習套件
樹莓派安裝 Python3 scikit-learn 函式庫

另外我在上奇出版的 "科學運算 Python 程式理論與應用" 一書中看到 IPython 的介紹, 這是 Python IDLE 互動式介面的改良版, 支援變數自動補全, 自動縮排, 指令回溯, 並內建許多有用函數與功能. 這麼好我也來安裝看看. 參考 :

Installing IPython

只要用 pip install ipython 即可 :

C:\Users\user>pip3 install ipython   
Collecting ipython
  Downloading ipython-6.2.1-py3-none-any.whl (745kB)
  ......
  ......
Requirement already satisfied: six in c:\python36\lib\site-packages (from traitlets>=4.2->ipython)
Collecting ipython-genutils (from traitlets>=4.2->ipython)
  Downloading ipython_genutils-0.2.0-py2.py3-none-any.whl
Collecting wcwidth (from prompt-toolkit<2 .0.0="" gt="" ipython="" p="">  Downloading wcwidth-0.1.7-py2.py3-none-any.whl
Installing collected packages: pickleshare, simplegeneric, pygments, parso, jedi, decorator, ipython-genutils, traitlets, wcwidth, prompt-toolkit, ipython
  Running setup.py install for simplegeneric ... done
Successfully installed decorator-4.1.2 ipython-6.2.1 ipython-genutils-0.2.0 jedi-0.11.1 parso-0.1.1 pickleshare-0.7.4 prompt-toolkit-1.0.15 pygments-2.2.0 simplegeneric-0.8.1 traitlets-4.3.2 wcwidth-0.1.7

如果被防火牆阻擋無法用 pip install ipython 下載安裝, 可先從 PyPi 網站下載 whl 檔 :

https://pypi.python.org/pypi/ipython

但是 ipython 有下面幾個相依函式庫, 需先下載安裝後才能安裝 ipython :

https://pypi.python.org/pypi/decorator
https://pypi.python.org/pypi/ipython_genutils
https://pypi.python.org/pypi/parso (須比 jedi 先安裝)
https://pypi.python.org/pypi/jedi
# https://pypi.python.org/pypi/pickleshare
https://pypi.python.org/pypi/prompt_toolkit (選 py3)
https://pypi.python.org/pypi/Pygments
https://pypi.python.org/pypi/simplegeneric (ZIP 檔)
https://pypi.python.org/pypi/traitlets
https://pypi.python.org/pypi/wcwidth

安裝過程如下 :

D:\Python>pip3 install decorator-4.2.1-py2.py3-none-any.whl
Processing d:\python\decorator-4.2.1-py2.py3-none-any.whl
Installing collected packages: decorator
Successfully installed decorator-4.2.1

D:\Python>pip3 install ipython_genutils-0.2.0-py2.py3-none-any.whl
Processing d:\python\ipython_genutils-0.2.0-py2.py3-none-any.whl
Installing collected packages: ipython-genutils
Successfully installed ipython-genutils-0.2.0

D:\Python>pip3 install parso-0.1.1-py2.py3-none-any.whl
Processing d:\python\parso-0.1.1-py2.py3-none-any.whl
Installing collected packages: parso
Successfully installed parso-0.1.1

D:\Python>pip3 install jedi-0.11.1-py2.py3-none-any.whl
Processing d:\python\jedi-0.11.1-py2.py3-none-any.whl
Requirement already satisfied: parso==0.1.1 in c:\python36\lib\site-packages (fr
om jedi==0.11.1)
Installing collected packages: jedi
Successfully installed jedi-0.11.1

D:\Python>pip3 install pickleshare-0.7.4-py2.py3-none-any.whl
Processing d:\python\pickleshare-0.7.4-py2.py3-none-any.whl
Installing collected packages: pickleshare
Successfully installed pickleshare-0.7.4

D:\Python>pip3 install prompt_toolkit-1.0.15-py3-none-any.whl
Processing d:\python\prompt_toolkit-1.0.15-py3-none-any.whl
Requirement already satisfied: six>=1.9.0 in c:\python36\lib\site-packages (from
 prompt-toolkit==1.0.15)
Requirement already satisfied: wcwidth in c:\python36\lib\site-packages (from pr
ompt-toolkit==1.0.15)
Installing collected packages: prompt-toolkit
Successfully installed prompt-toolkit-1.0.15

D:\Python>pip3 install Pygments-2.2.0-py2.py3-none-any.whl
Processing d:\python\pygments-2.2.0-py2.py3-none-any.whl
Installing collected packages: Pygments
Successfully installed Pygments-2.2.0

D:\Python>pip3 install simplegeneric-0.8.1.zip
Processing d:\python\simplegeneric-0.8.1.zip
Installing collected packages: simplegeneric
  Running setup.py install for simplegeneric ... done
Successfully installed simplegeneric-0.8.1

D:\Python>pip3 install traitlets-4.3.2-py2.py3-none-any.whl
Processing d:\python\traitlets-4.3.2-py2.py3-none-any.whl
Requirement already satisfied: ipython-genutils in c:\python36\lib\site-packages
 (from traitlets==4.3.2)
Requirement already satisfied: decorator in c:\python36\lib\site-packages (from
traitlets==4.3.2)
Requirement already satisfied: six in c:\python36\lib\site-packages (from traitl
ets==4.3.2)
Installing collected packages: traitlets
Successfully installed traitlets-4.3.2

D:\Python>pip3 install wcwidth-0.1.7-py2.py3-none-any.whl
Processing d:\python\wcwidth-0.1.7-py2.py3-none-any.whl
Installing collected packages: wcwidth
Successfully installed wcwidth-0.1.7

D:\Python>pip3 install ipython-6.2.1-py3-none-any.whl
Processing d:\python\ipython-6.2.1-py3-none-any.whl
Requirement already satisfied: traitlets>=4.2 in c:\python36\lib\site-packages (
from ipython==6.2.1)
Requirement already satisfied: pickleshare in c:\python36\lib\site-packages (fro
m ipython==6.2.1)
Requirement already satisfied: jedi>=0.10 in c:\python36\lib\site-packages (from
 ipython==6.2.1)
Requirement already satisfied: decorator in c:\python36\lib\site-packages (from
ipython==6.2.1)
Requirement already satisfied: pygments in c:\python36\lib\site-packages (from i
python==6.2.1)
Requirement already satisfied: prompt-toolkit<2.0.0,>=1.0.4 in c:\python36\lib\s
ite-packages (from ipython==6.2.1)
Requirement already satisfied: simplegeneric>0.8 in c:\python36\lib\site-package
s (from ipython==6.2.1)
Requirement already satisfied: colorama; sys_platform == "win32" in c:\python36\
lib\site-packages (from ipython==6.2.1)
Requirement already satisfied: setuptools>=18.5 in c:\python36\lib\site-packages
 (from ipython==6.2.1)
Requirement already satisfied: ipython-genutils in c:\python36\lib\site-packages
 (from traitlets>=4.2->ipython==6.2.1)
Requirement already satisfied: six in c:\python36\lib\site-packages (from traitl
ets>=4.2->ipython==6.2.1)
Requirement already satisfied: parso==0.1.1 in c:\python36\lib\site-packages (fr
om jedi>=0.10->ipython==6.2.1)
Requirement already satisfied: wcwidth in c:\python36\lib\site-packages (from pr
ompt-toolkit<2.0.0,>=1.0.4->ipython==6.2.1)
Installing collected packages: ipython
Successfully installed ipython-6.2.1


在命令列輸入 ipython 即進入互動式介面, 它會對每一次的輸入進行編號, 例如 In[1], In[2], .... 如果忘記冪次函數 pow() 的拼法, 只要輸入 p 再按 tab 鍵, 下方就會列出所有 p 開頭的函數 :

C:\Users\user>ipython 
Python 3.6.1 (v3.6.1:69c0db5, Mar 21 2017, 18:41:36) [MSC v.1900 64 bit (AMD64)]
Type 'copyright', 'credits' or 'license' for more information
IPython 6.2.1 -- An enhanced Interactive Python. Type '?' for help.

In [1]:

In [1]: print("ok")
ok

In [2]: p     (按 tab 鍵)
          pass                      print()
          PendingDeprecationWarning ProcessLookupError
          PermissionError           property                  >
          pow()                     Pictures/

In [3]: exit      (離開 Ipython)






跳出 Ipython 可輸入 exit 回到命令列,

嗯, 真的比 IDLE 介面好用, 光是指令回溯就可以省掉不少敲指令時間. 接下來就用 ipython 來玩一下 Matplotlib 繪圖功能, 輸入下列指令 :

import numpy as np
import matplotlib.pyplot as plt
x=np.arange(0, 2, 0.05)
y=np.sin(2*np.pi*x)
plt.plot(x, y)
plt.show()

結果如下 :

C:\Users\user>ipython
Python 3.6.1 (v3.6.1:69c0db5, Mar 21 2017, 18:41:36) [MSC v.1900 64 bit (AMD64)]
Type 'copyright', 'credits' or 'license' for more information
IPython 6.2.1 -- An enhanced Interactive Python. Type '?' for help.

In [1]: import numpy as np

In [2]: import matplotlib.pyplot as plt

In [3]: x=np.arange(0, 2, 0.05)

In [4]: y=np.sin(2*np.pi*x)

In [5]: plt.plot(x,y)
Out[5]: [<matplotlib.lines.Line2D at 0x2a52305fb38>]

In [6]: plt.show()





圓周率在 Numpy 中為一屬性 Numpy.pi, 注意, plot() 只是將建立的圖存在一個 Line2D 物件而已, 必須呼叫 show() 才會顯示圖形.

2018-02-25 補充 :

在 Python 3.6.4 版直接安裝 Scipy 就會同時安裝 Numpy 了, 因此程序只要 4 個即可 :
  1. pip3 install scipy
  2. pip3 install matplotlib
  3. pip3 install pandas
  4. pip3 install scikit-learn

2018年1月13日 星期六

太陽光電設置班第六課

可能是寒流來襲爬不起床, 今天早上到課人數明顯變少, 但第二節後就陸續到齊. 課程已近尾聲, 早上老師要我們先練習紙上配線, 待助教檢查過後就上頂樓實地配線. 本周工作忙沒練習多少, 原本已很熟的獨立型竟幾乎忘光了, 所以又再畫了三張以恢復手感. 但太晚上去每一個工作站都有人了, 只好先在旁觀摩. 輪到我要上場時卻已 11 點多, 時間不太夠, 我想我又沒參加檢定, 只要了解原理就好, 不需練熟練度啦! 所以就讓要檢定的同學多練習吧!





今天可能是太冷, 工會的人沒來, 連帶也沒有熱開水與咖啡可泡, 下午上障礙排除時就昏昏欲睡, 與前五次上課大不相同, 之前一天課程下來都喝三杯左右, 咖啡真是提神啊! 四點下課時看到學校圍牆邊的垂直式風電, 仔細端詳了一下覺得這可以用 PVC 管與木條來做,




結果在拍此相片時沒看到地上有一鐵桿, 一不小心就被絆倒, 摔了個四腳朝天. 似乎是在告訴我甚麼 (讓我想到梅花易數), 結果騎到澄清路才想起沒簽退, 趕緊又跑回教室, 還好人還沒走. 剩下一堂半課程了, 我對太陽光電了解得差不多了, 學習焦點應該拉回 R 語言, Python, ML, 以及物聯網了.

2018年1月10日 星期三

金石堂購書三本

昨天為了用掉金石堂 50 元禮券, 購買了下列兩本書 :

Deep Learning-用Python進行深度學習的基礎理論實作 定價 $580 79 折 458
斷糖生酮飲食法:日本名醫教你吃出燃脂抗老的酮體能量,打造不生病好體質 定價 $299 7 折 209

合計 661-50=611, 約定價 7 折.

今天又還有一張 50 元到期, 買了蔡立耑的書 :

金融科技實戰:Python與量化投資 定價 $650 79 折 514

合計 514-50=464, 約 71 折左右.

電子書 : How to Think Like a Computer Scientist

Pinterest 看到這本 Open Book 專案的網路電子書 :

How to Think Like a Computer Scientist

真是太棒了, 可說是整本原文書的網頁化, 只需要簡單的英文就可以看懂. 其實現在網路學習資源非常多, 缺的只是學習進取的心而已.

2018年1月8日 星期一

2018 年第 1 周記事

過去一周才是 2018 年第一周, 我就覺得奇怪, 怎麼 2017 我只算到 51 周, 原來是自己搞錯了. 週四幫姊姊訂 2/1 的高鐵, 有大學生五折優惠, 但信用卡付款後, 週五才得知宿舍這學期只能住到 1/31, 所以又改定 1/31 的票, 但只剩 7 折了. 原以為要退票重訂, 研究了一下才知道不需如此, 只要上網修改搭乘日期即可.

這兩周年度交接之際買了七本以上的書, 揮霍了不少錢, 但我就讀書這點嗜好, 能得好書一讀就算揮霍些也不為過. 另外就是我的 "借書症", 每周日去市場後總是忍不住進去附近的圖書館, 幾乎每周都能挖到寶, 但時間有限怎看得完, 現在越借越多, 不清理不行.

週日中午小舅媽邀一起去溪州阿龍的姑姑開的麵攤吃麵, 之前有提過下次要去時帶我去, 所以中午就不煮了, 四個人搭一台車去. 麵攤只賣乾麵, 湯麵, 以及切料而已, 但其自製粉腸非常好吃, 12 點未到已銷售一空, 還有人整條買回去.

週六上太陽光電課時, 要參加技術士檢定的同學開始繳交報名表, 我雖不參加檢定, 但還是非常認真學習, 除了勤於紙上練習外, 術科配線也不含糊. 週日下午太陽光電班同學發哥來訪, 專程來看我家頂樓大小, 看是否能裝設屋頂太陽能電廠. 勘查結果是不行, 因鄉下家是民國 65 年自行興建的農舍, 恐怕無法裝設. 他說只能裝獨立型自產自用而已.

2018年1月6日 星期六

好書 : Python 專家實踐指南

周五去圖書館拿預約到館的 "Python 專家實踐指南" :

Source : 天瓏

稍微翻閱了一下, 才發現這不是一本程式技術的書, 而是 "如何寫好 Python" 的書, 例如怎樣撰寫符合 Python 常見風格的程式碼如 PEP8, PEP20 等; 如何測試與打包發布 Python 程式等等, 範圍其實很雜很大, 不只是 coding 而已, 真的是專家等級, 我自認還是屬於羽量級, 有很多還用不到.

在樹莓派中安裝 pep8 必須用 sudo 以系統管理員身分 :

pi@raspberrypi:~ $ sudo pip3 install pep8 
Downloading/unpacking pep8
  Downloading pep8-1.7.1-py2.py3-none-any.whl (41kB): 41kB downloaded
Installing collected packages: pep8
Successfully installed pep8
Cleaning up...

這樣就可以用 pep8 指令來檢查 Python 程式是否符合 PEP8 風格 :

pi@raspberrypi:~ $ pep8 reportip2.py   
/usr/local/lib/python3.4/dist-packages/pep8.py:2124: UserWarning:

pep8 has been renamed to pycodestyle (GitHub issue #466)
Use of the pep8 tool will be removed in a future release.
Please install and use `pycodestyle` instead.

原來 pep8 已有繼任者 pycodestyle, 那就用新的吧!

$ pip install pycodestyle  
$ pycodestyle ...

  '\n\n'
reportip2.py:2:1: E265 block comment should start with '# '
reportip2.py:6:1: E402 module level import not at top of file
reportip2.py:7:1: E402 module level import not at top of file
reportip2.py:8:1: E402 module level import not at top of file
reportip2.py:9:1: E402 module level import not at top of file
reportip2.py:10:1: E402 module level import not at top of file
reportip2.py:11:1: E402 module level import not at top of file
reportip2.py:12:1: E402 module level import not at top of file
reportip2.py:13:1: E402 module level import not at top of file
reportip2.py:14:1: E402 module level import not at top of file
reportip2.py:15:1: E402 module level import not at top of file
reportip2.py:23:33: E231 missing whitespace after ','
reportip2.py:29:1: E302 expected 2 blank lines, found 1
reportip2.py:33:25: E222 multiple spaces after operator
reportip2.py:34:31: E231 missing whitespace after ','
reportip2.py:34:38: E231 missing whitespace after ','
reportip2.py:48:25: E203 whitespace before ','
reportip2.py:49:12: E111 indentation is not a multiple of four
reportip2.py:50:12: E111 indentation is not a multiple of four
reportip2.py:51:12: E111 indentation is not a multiple of four
reportip2.py:54:1: E302 expected 2 blank lines, found 1
reportip2.py:54:18: W291 trailing whitespace
reportip2.py:56:25: E231 missing whitespace after ','
reportip2.py:56:30: W291 trailing whitespace
reportip2.py:57:11: E225 missing whitespace around operator
reportip2.py:61:1: E302 expected 2 blank lines, found 1
reportip2.py:78:5: E301 expected 1 blank line, found 0
reportip2.py:78:19: E231 missing whitespace after ','
reportip2.py:79:37: E231 missing whitespace after ','
reportip2.py:82:40: E231 missing whitespace after ','
reportip2.py:83:46: E231 missing whitespace after ','
reportip2.py:85:1: E302 expected 2 blank lines, found 1
reportip2.py:93:11: E225 missing whitespace around operator
reportip2.py:94:10: E225 missing whitespace around operator
reportip2.py:95:12: E225 missing whitespace around operator
reportip2.py:103:33: E231 missing whitespace after ','

原來 PEP8 有新版的模組稱為 pycodestyle :

pi@raspberrypi:~ $ sudo pip3 install pycodestyle   
Downloading/unpacking pycodestyle
  Downloading pycodestyle-2.3.1-py2.py3-none-any.whl (45kB): 45kB downloaded
Installing collected packages: pycodestyle
Successfully installed pycodestyle
Cleaning up...

pi@raspberrypi:~ $ pycodestyle reportip2.py   
reportip2.py:2:1: E265 block comment should start with '# '
reportip2.py:23:33: E231 missing whitespace after ','
reportip2.py:29:1: E302 expected 2 blank lines, found 1
reportip2.py:33:25: E222 multiple spaces after operator
reportip2.py:34:31: E231 missing whitespace after ','
reportip2.py:34:38: E231 missing whitespace after ','
reportip2.py:48:25: E203 whitespace before ','
reportip2.py:49:12: E111 indentation is not a multiple of four
reportip2.py:50:12: E111 indentation is not a multiple of four
reportip2.py:51:12: E111 indentation is not a multiple of four
reportip2.py:54:1: E302 expected 2 blank lines, found 1
reportip2.py:54:18: W291 trailing whitespace
reportip2.py:56:25: E231 missing whitespace after ','
reportip2.py:56:30: W291 trailing whitespace
reportip2.py:57:11: E225 missing whitespace around operator
reportip2.py:61:1: E302 expected 2 blank lines, found 1
reportip2.py:65:9: E722 do not use bare except'
reportip2.py:68:13: E722 do not use bare except'
reportip2.py:73:17: E722 do not use bare except'
reportip2.py:78:5: E301 expected 1 blank line, found 0
reportip2.py:78:19: E231 missing whitespace after ','
reportip2.py:79:37: E231 missing whitespace after ','
reportip2.py:82:40: E231 missing whitespace after ','
reportip2.py:83:46: E231 missing whitespace after ','
reportip2.py:85:1: E302 expected 2 blank lines, found 1
reportip2.py:93:11: E225 missing whitespace around operator
reportip2.py:94:10: E225 missing whitespace around operator
reportip2.py:95:12: E225 missing whitespace around operator
reportip2.py:103:33: E231 missing whitespace after ','

第六章介紹如何打包 (或凍結 freeze) Python 程式, 五種工具如下表 :

 Pyinstaller cx_Freeze py2app py2exe bbFreeze
 Python3 YES YES YES YES -
 Licence GPL PSF MIT MIT Zlib
 Windows YES YES - YES YES
 Linux YES YES - - YES
 OS X YES YES YES - -

其中 Pyinstaller 與 cx_Freeze 頗受好評. Pyinstaller 用法參考 :

將Python腳本打包成可執行文件

其安裝指令為

$ pip install pyinstaller

打包程式 :

$ pyinstaller script.py

這樣會產生一個 .spec 檔與 build (日誌), dist (可執行檔與相依函式庫) 兩個目錄, 接著需編輯 .spec 檔以自訂建構內容.

安裝 cx_Freeze  :

$ pip install cx_Freeze

建構腳本 :

$ cxfreeze-quickstart

打包 :

$ python setup.py build_exe  (Windows 可執行檔)
$ python setup.py build_msi  (Windows 可執行檔與相依檔案)
$ python setup.py build_rpm  (Linux)

另外在第十章資料處理舉出了 Python 常用的資料工具函式庫 :

  1. Numpy :
    提供多維陣列與線性代數工具, 速度最佳化, 是 SciPy 的一部分, 從 Scipy 中獨立出來.
  2. SciPy :
    提供工程與科學相關函式與工具, 例如線性代數, 信號處理, 積分, 求根, 與統計等.
  3. Matplotlib :
    提供科學繪圖函式庫.
  4. Pandas :
    提供可儲存, 合併, 分群, 迴歸, 索引, 視窗, 與子集的序列與 DataFrame 物件.
  5. Scikit-Learn :
    提供機器學習演算法.
  6. Nltk :
    提供自然語言工具組, 可用多種語言進行資料建模與訓練. 
  7. Rpy2 :
    提供 R 語言統計套件介面, 可從 Python 執行 R 語言, 並在兩個環境之間傳遞資料.
  8. CV2 (OpenCV) :
    提供電腦視覺即時影像分析函數庫, 例如人臉辨識演算法.
  9. Scikit-image :
    提供影像處理函式庫. 
原來 Python 還能透過 Rpy2 與 R 語言協同作業哩!

太陽光電設置班第五課

這兩天陰雨綿綿, 昨晚更下了一整晚的雨, 好在早上雨停了. 學期末段考將屆, 二哥的 APCS 課暫停, 所以我早上就直接去正修上課.

雖然白天沒下雨, 但今天一整天都是教室課, 早上先複習併聯型配線圖, 做完紙上練習再用黃老師特製的配線箱模擬拉線, 好像是練武功的木人, 練熟了下周再上頂樓配線箱實作. 不過練習時間有限, 早上我只做完交流配線箱部分. 好在這禮拜我有練習紙上配線, 線路圖已經記得住了. 老師說配線要練到 52 分鐘完成的目標, 一定要多做紙上練習, 上場時才能毫不猶豫.  




下午複習獨立型配線箱, 這比並聯型複雜些, 因為牽涉到蓄電池就有充放電能量流動問題, 光是分流器與電表就要三個. 一邊配線一邊聽同學說去年以來註冊的綠能公司超過一千家, 而且現在申請綠能屋頂的件數非常之多, 台電審核速度沒這麼快. 

好書 : 打造Web物聯網-使用Node.js與Raspberry Pi

今天在市圖網站找到這本到館新書 :

打造Web物聯網 :使用Node.js與Raspberry Pi


Source : 誠品


已先預約, 但展示中不知何時會到. 此書目前博客來 7 折 $434, 扣掉生日折價券 50 元為 384 元, 約打 62 折, 很划算. 書到之後看看若值得就買下來.

市圖還有一本碁峰出的 Node.js 書也不錯 :

Node.js 實戰手冊

Source : 金石堂


不過最近借太多書了, 消化不良, 以後再借.

2018年1月5日 星期五

還書一批 : 架站書籍

下面這三本關於 WordPress 與 Drupal 的架站書目前沒時間鑽研, 故先還給市圖 :
  1. Wordpress網路拉皮術 :手機、平板、PC都好用的響應式設計 
  2. 水滴架站什麼都賣 :用Drupal打造我的網路商城 (鼓山)
  3. 用Drupal輕鬆架出商業網站 :網路商店x報名平臺x預約系統x拍賣平台 (苓雅)
要精通一套架站軟體調校其實不是三天兩天的事, 目前會先聚焦在 Joomla! 上.

購買 Sony 藍芽耳機 MBH20

因騎機車時常會接到二哥電話, 行進中不可接聽, 因此想買個藍芽耳機, 在露天剛好找到高雄可面交的這個, 昨晚去母校還書時順路到大豐二路取貨 :

# 露天 MBH20 $300
Sony MBH20

Type : RD0150  SN : 17020636000F404

這款比以前壞掉那個好的地方是 - 可以聽音樂. 舊的就是因為只能聽電話, 用的機會不多, 放久了電池就壞掉了.

今天早上上班時我就戴著聽日語 mp3, 即使騎機車仍然聽得很清楚.

2018年1月3日 星期三

2017 年第 52 周記事

這是 2017 年的最後一周了, 人生就是一串數字, 串起各種回憶, 但遺忘的多, 記得的總是比較少. 時間就像我房外不遠處小圳中川流不息的水, 它不斷地流逝, 在桌前靜靜讀書的時候就可以聽到那潺潺的水流聲, 看似平淡, 但那就是生命之流啊!

姊姊週五 12/29 晚上坐自強號回到高雄, 聽她頻頻咳嗽, 原來聖誕節第二天感冒請假沒去上課, 拖到回高雄才要去看醫生, 結果楊醫師卻休診四天. 週六回到鄉下採了一些魚腥草燉麥芽糖酸梅湯給她喝, 但似乎效果不顯著. 冬天的魚腥草不像夏天時那麼茂密, 品質可能也不甚好.

元旦連假雖說休三天, 但週六我要上課, 周一中午姊姊又要搭車回台北, 所以也是如往常只休一天而已. 元旦過後就準備迎接舊曆年了, 一整年大部分的時間都在忙, 這時除了要來個大掃除, 大整理外, 應該放慢腳步來回顧一下做了甚麼, 想做又沒做的有哪些, 也要來個大盤點.

2018年1月2日 星期二

Arduino + LoRa 模組測試

這篇是去年 10 月底對 LoRa 模組進行初步測試的紀錄, 後來忙著幫二哥準備 APCS 而暫停下來. 昨天有網友問我空曠處實測距離多少, 才想起這篇還沒完成的草稿, 稍作整理如下備查. 在傳送距離方面, 網友與我的實測距離都約 200~250 米而已, 據說使用 IPEX 天線似乎沒有好到哪裡去, 實在殘念! 我還抱著一絲希望的說.

會接觸 LoRa 是因為去年十月初有另一位網友詢問我有無用過 LoRa, 當時我連買了放在零件箱好久的 nRF24L01 模組都還沒動哩! 為此我除了找出 nRF24L01 先測試一番以產生比較資料外, 還上網對此新興無線射頻技術做了初步研究, 整理了一篇知識摘要, 參見 :

長距離低功耗無線通訊技術 LoRa

接著在露天購買了一對最便宜的 LoRa 模組來測試 (跟 nRF24L01 一樣要成對地買, 一個傳送, 一個接收, 或者互相傳送接收), 此板用的是 SX1278 晶片 (433 MHz)  :

[史塔克實驗室][Arduino/RPi]每個180元2個一組販售SX1278 Lora module 模組433MHz $180

由於這是 2.0mm 腳距的裸板, 所以特地跑去禾樺買了 2.0 mm 的排針與排母, 在焊接前試試看到底要用排針或排母比較適合, 結果發現排針根本不能用, 因為 2.0mm 的排針比較細, 杜邦線母頭插上去鬆鬆的會接觸不良, 應該要用排母才對, 因為 2.0mm 的排母上的洞與一般 2.54mm 者一樣, 插杜邦線沒問題.

我買的這組 LoRa 模組每邊 8 隻腳, 其腳位布局如下 :


 DIO2 GND 
 DIO1 MISO 
 DIO0 MOSI 
 3.3V SCK 
 DIO4 NSS 
 DIO3 RESET 
 GND DIO5 
 ANT GND 


由於 ANT 腳要焊彈簧天線, 因此左邊的排母只要 7 隻腳, 而右邊的則需 8 隻腳, 使用小型電鑽前面裝上鑽石圓盤分別切出 7 支與 8 支腳的排母各一對, 然後用三秒膠少許加以固定後進行焊接. 注意, 三秒膠不可用太多, 否則萬一滲入排母內會讓排針插不下去.


Lora 板子焊好後就可以進行測試了, 我使用 Arduino 當作 MCU 主控, 首先是到下列 GitHub 網站下載 Arduino 的 Lora 函式庫 :

https://github.com/sandeepmistry/arduino-LoRa

按右邊的 "Clone or download" 鈕, 選 "Download ZIP" 下載壓縮檔 arduino-LoRa-master.zip, 將其複製到 Arduino IDE 安裝目錄的 libraries 下解開即可. 重新開啟 IDE 就可存取到此函式庫了. 此函式庫的 API 說明如下 :

https://github.com/sandeepmistry/arduino-LoRa/blob/master/API.md

此函式庫使用 SPI 協定與 LoRa 模組通訊, 預設傳輸速率是 10 MHz. 接下來是硬體接線, 此 LoRa 模組採用 SPI 介面 (也有用 Serial 介面的), Arduino 有特定的 SPI 接腳, 與 LoRa 的預設對應如下 :


不過其中 NSS, RESET, 與 DIO0 這三隻腳不一定要對應到 D10, D9, 與 D2 這三支 Arduino 腳, 可以連接到除 D13, D12, D11 以外的任何 DIO 腳位, 但在程式中要用 LoRa.setPins(NSS, RESET, DIO0) 指令指定.

測試 1 :

傳送端程式 :

#include <SPI.h>
#include <LoRa.h>

int counter=0;  //傳送次數計數器

void setup() {
  Serial.begin(9600);
  while (!Serial);  //等待序列埠起始完畢
  Serial.println("LoRa Sender");
  if (!LoRa.begin(433E6)) {  //起始 433MHz LoRa
    Serial.println("Starting LoRa failed!");
    while (1);
    }
  }

void loop() {
  Serial.print("Sending packet: ");
  Serial.println(counter);
  LoRa.beginPacket();  //封包傳送開始
  LoRa.print("hello ");  //封包內容
  LoRa.print(counter);  //封包內容
  LoRa.endPacket();  //封包傳送結束
  counter++;  //計數器增量 1
  delay(5000);
  }


接收端程式 :

#include <SPI.h>
#include <LoRa.h>

void setup() {
  Serial.begin(9600);
  while (!Serial);  //等待序列埠起始完畢
  Serial.println("LoRa Receiver");
  if (!LoRa.begin(433E6)) { //起始 LoRa
    Serial.println("Starting LoRa failed!");
    while (1);
    }
  }

void loop() {
  int packetSize=LoRa.parsePacket(); //讀取剖析 LoRa 封包大小
  if (packetSize) { //若有封包進來
    Serial.print("Received packet '");
    while (LoRa.available()) { //若接收緩衝器有內容
      Serial.print((char)LoRa.read());  //讀取緩衝器內容並輸出階收到的封包
      } 
    Serial.print("' with RSSI="); //輸出接收封包之 RSSI
    Serial.print(LoRa.packetRssi());  //顯示接收信號強度
    Serial.print(" and SNR="); //輸出接收封包之 SNR (信噪比)
    Serial.println(LoRa.packetSnr());  //顯示接收信號信噪比
    }
  }

序列埠監控視窗輸出結果如下, 收到訊號時會顯示 "Received packet ... RSSI= .... SNR=...." :
.....
irqFlags 0
irqFlags 10
irqFlags 40
Received packet 'hello 29' with RSSI=-39 and SNR=16.00
irqFlags 0
irqFlags 0
irqFlags 0
irqFlags 0
irqFlags 0
irqFlags 0
irqFlags 0
irqFlags 0
irqFlags 0
irqFlags 0
irqFlags 80
irqFlags 0
irqFlags 0
irqFlags 0
irqFlags 0
irqFlags 0
irqFlags 0
irqFlags 0
irqFlags 0
irqFlags 80
irqFlags 0
.....
irqFlags 10
irqFlags 40
Received packet 'hello 30' with RSSI=-51 and SNR=15.75
irqFlags 0
irqFlags 0
irqFlags 0
irqFlags 0
irqFlags 0
irqFlags 0
irqFlags 0
irqFlags 0
irqFlags 0
irqFlags 0
irqFlags 80
irqFlags 0
.....

其中 RSSI (Received Signal Strength Indicator) : 接收信號强度指示.

用彈簧天線於空曠地區實測距離約 250 公尺, 似乎只比 nRF24L01 的 100 公尺長兩倍多而已, 與產品說明中所說的 1 公里相差達 4 倍. 不過信號穿透力可達 2~3 層樓, 在電梯中亦可收到信號, 這就比 nRF24L01 出色多了, nRF24L01 只要 5 公尺外轉個牆角就 GG 了, 參考 :

Arduino 無線傳輸模組 NRF24L01 測試

測試距離方面, 有空我還是會買支 IPEX 或其他廠家的 LoRa 模組來驗證看看.

參考 : 

Arduino Arduino module communication by Lora Sx1278
https://github.com/matthijskooijman/arduino-lmic
【Acsip LoRa實作1】快速開發LoRa通訊功能-SPI介面篇
An Arduino library for sending and receiving data using LoRa radios
LoRa 的 Arduino 函式庫
【Acsip LoRa實作1】快速開發LoRa通訊功能-SPI介面篇
WLK01S78-TH 無線模組 LORA模組 SX1278數傳模組 w7 056 [5059647] $260
# LoRa 測試資料下載  (測試地圖快照) (測試地形圖)
<微控制器科技> Pycom LoPy IoT 三合一開發板 (LoRa+BLE+WiFi) $1350
Pycom LoPy - LoRa+WiFi+Bluetooth MicroPython IoT Platform £32.5
https://github.com/a3rd/lora-inair4
SX1278 LoRa擴頻無線模組 433Mhz $220
大陸模組資料下載
https://drive.google.com/drive/folders/0BywdxdAWyMLcWXpFNF9QVWhHZHc
SX1278 LOra擴頻 電力抄表模組 5km無線收發模組SX1276模組 $200
iFrogLab iL-LORA1272 超遠端15公里LoRa資料傳遞和接收模組 for Arduino 和 樹梅派 $850
iFrogLab iL-LORA1272-A LoRa 資料傳遞和接收模組 韌體全面更新為1.1版 $850
98 Mailbag #8: LoRa, ESP8285, ESP32 in a WiPy Python board, A6C with camera
# LoRa 範例程式下載
Setting Up the Modtronix InAir4 with Arduino

2018-01-03 補充 :

下面這部影片測試 LoRa 的耗電情形 :

#120 LoRa on batteries: How long does it last?