2017年8月12日 星期六

[IoT 終端裝置應用] Python基本環境架設與研究

Windows安裝流程(本範例以Windows10) :
















選擇自訂安裝
























此頁直接全選 > Next.
























若沒有設定環境變數 在命令提示字元(cmd)下打python 會無法辨識:



接著如下是環境變數設定 先確認我們安裝的路徑是正確的 確定是在C:\底下 而非program files(會有系統保護的問題,未來在安裝或更新套件會有問題)



















隨即 到 我的電腦(右鍵內容) > 環境變數(點選編輯系統變數) > 將路徑貼上至Path的內容後方,記得用逗號分開。





















接著我們先安裝pip模組:就可以用pip安裝其他模組
https://pip.pypa.io/en/stable/installing/
必須先另存py檔https://bootstrap.pypa.io/get-pip.py
下個步驟是執行它python get-pip.py













再來我們就可以透過python指令在cmd模式下 安裝pyserial套件跟 pyvisa套件了 :
python -m pip 可以查看模組    pip模組介紹  pip套件官網(取代easy_install的python套件安裝神器)
python -m pip install -U pip 可以更新pip模組
python -m pip install -U pyserial 可以安裝pyserial模組,並更新到最新版本
python -m pip install -U pyvisa 可以安裝pyvisa模組,並更新到最新版本   pyvisa官網
python -m pip install -U junit-xml 可以安裝junit-xml模組
python -m pip install -U pytest 可以安裝pytest模組
python -m pip install -U openpyxl //Exel專用模組
python -m pip install -U pillow //圖形處理專用模組
python -m pip install -U PyQt5 //Python下的UI開發
python -m pip install -U bs4 //Python下的網路爬蟲專用模組

python -m pip install -U PyPDF2 //PDF專用模組
python -m pip install -U xlsxwriter //Excel寫入專用模組
python -m pip install -U Python-Docx //Word專用模組
python -m pip install -U subprocess //工作排成與程式啟動專用模組
python -m pip install -U pyautogui   //自動化GUI操作模組
python -m pip install -U paho-mqtt

******************* OpenCV相關模組庫 *******************
python -m pip install -U Matplotlib //Python下的繪圖庫模組 常用來產生報表
python -m pip install -U numpy //Python的科學運算 矩陣相關...
python -m pip install .\opencv_python-3.3.0+contrib-cp36-cp36m-win32.whl
//關於opencv的cv2模組 影像處理與操作,
安裝教學可以參考 : https://www.youtube.com/watch?v=ulJdZn0qBCQ
下載安裝包地址(opencv for python3) : http://www.lfd.uci.edu/~gohlke/pythonlibs/
******************* OpenCV相關模組庫 *******************


pip更新模組指令 : python -m pip install --upgrade pip (更新pip模組) 















為了確定此兩套件順利安裝,我們可以在cmd打python進入python mode或是開啟python專用的IDE (IDLE) 並打入
import visa(enter鍵送出)
import serial(enter鍵送出)
來確定是否有錯誤訊息跳出,若順利執行則安裝成功













Ubuntu12.04 64bit安裝流程  :
wget https://www.python.org/ftp/python/3.5.1/Python-3.5.1.tar.xz
tar xfvJ Python-3.5.1.tar.xz
cd Python-3.5.1
./configure --prefix=/opt/python3.5
make
# To make idle3.5, you need tk's development to produce tkinter
sudo apt-get install tk8.6-dev
sudo make install
Your python 3.5 interpreter will be located in /opt/python3.5/bin/python3.5. Your Integrated DeveLopment Environment is also found in /opt/python3.5/bin/idle3.5.
To facilitate use you can symlink these files to a location on your $PATH like so:
sudo ln -s /opt/python3.5/bin/python3.5 /usr/local/bin/py3.5
sudo ln -s /opt/python3.5/bin/idle3.5 /usr/local/bin/idle3.5
After this, just typing py3.5 from the command line will use python 3.5, while at the same time, python 3.4 will remain untouched, and will not cause any "breakage" on your system. Also, idle3.5will bring up the IDLE editor with the python 3.5.1 shell.










OSX10 (Mac OS)安裝流程 (感謝RD同仁610提供) :
至官網點選Mac OS X版本的python3.5.1環境







下載後直接點選主程式進行安裝



























通過版權的閱讀並打完系統管理員密碼後 安裝後所見如下 :



























在mac的command line模式中 輸入python會進入MacOS內建python2.7.1,所以往後要執行時需要特別鍵入python3才能啟動python3的編輯
























=====================================================================
Python專用開發工具-PyCharm

關閉波浪虛線檢查



說明:如上圖所示,PyCharm會開啟自動檢查,指到會顯示Pep8 indentation contains tabs.
在請教google大神後查詢到PyCharm 2016.1 Help-Changing Indentation 按下Ctrl+Alt+L之後即可解決!!!

出現pep8 expected 2 blank lines found 1

expected two blank lines pep8 warning in python

每個function的定義段必須先空兩格 否則會被PyCharm檢查出來

顯示行號
File --> Settings -->Editor -->Appearance


字體大小修改
File --> Settings -->Editor -->Colors & Fonts--> Font
Scheme -->Save as--> select copy scheme--> change font size
設定字體需要自己定義一個樣式集,不能再IDE原生樣式集上面做修改


2017年8月7日 星期一

[IoT上層應用] Python資料分析與儲存 - 使用xlsxwriter模組


程式碼參考 :
https://github.com/kunhsien/PyExample/tree/master/PyXlsxWriter


範例的程式進入點 main 位於Battery_analysis.py


def main():
    sendThr = threading.Thread(target=parse_value)
    sendThr.start()


if __name__ == '__main__':
    main()


我們用了threading的模組 去重複執行parse_value


def parse_value():
 index_Volt = 6
 index_Cap = 2
 indwx_Temp = 10
    for i in range(1000):
        message = "[battery_check]BATT cap 99 cap_count 0 vol 3981000 vol_count 0 temp 229 temp_count 0 batt_no_count 0 \r\n'"
        s_toke = message
        s_token = re.split(' ', s_toke)
        print(str(s_token))
        Volt_value = s_token[index_Volt]
        Cap_value = s_token[index_Cap]
        Temp_value = s_token[indwx_Temp]
        print("[Battery_analysis] - Volt_value: " + str(Volt_value) + ", Cap_value: " + str(Cap_value) + ", Temp_value: " + str(Temp_value) +"\n")
        for key in range(0,15):
            xls_report.VOLTAGE_QUEUE[key].append(Volt_value)
            xls_report.CAPACITY_QUEUE[key].append(Cap_value)
            xls_report.TEMPERTURE_QUEUE[key].append(Temp_value)
    for key_print in range(0, 15):
        print("KEY" + str(key_print) +" temperture : " + str(xls_report.TEMPERTURE_QUEUE[key_print]) + ".\n")
        print("KEY" + str(key_print) + " capacity : " + str(xls_report.CAPACITY_QUEUE[key_print]) + ".\n")
        print("KEY" + str(key_print) + " voltage : " + str(xls_report.VOLTAGE_QUEUE[key_print]) + ".\n")
    xls_report.battery_queue_finish = True
    xls_report.write_to_excel()


在parse_value中我們使用for迴圈對15個key component塞了三個資料 電壓 溫度 容量
塞進去queue之後 我們塞了一個flag 告訴系統 我們完成塞queue的動作了
最後執行write_to_excel函式

def write_to_excel():
    #if (battery_queue_finish == True):
        WORKBOOK = xlsxwriter.Workbook("Battery_values.xlsx") # 新增excel檔案
        sheet_Capacity = WORKBOOK.add_worksheet("Capacity") #新增表單 命名Capacity
        sheet_Voltage = WORKBOOK.add_worksheet("Voltage") #新增表單 命名Voltage
        sheet_Temperture = WORKBOOK.add_worksheet("Temperture") #新增表單 命名Temperture
        for index_num in range(len(Title_ADDR)):
            sheet_Capacity.write(Title_ADDR[index_num], "Key" + str(index_num))
            sheet_Voltage.write(Title_ADDR[index_num], "Key" + str(index_num))
            sheet_Temperture.write(Title_ADDR[index_num], "Key" + str(index_num))
        print("[Xls_report] - Write_to_excel: Sheet -  \n")
        for key_index in range(0,15):
            print("Saving Battery information for Key(" +str(key_index)+")...\n")
            for TempQ_index in range(len(TEMPERTURE_QUEUE[key_index])):
                TempAddr = GetAndIncrease_Addr(key_index, 'Temperture')
                print(str(TempAddr))
                sheet_Temperture.write(TempAddr, TEMPERTURE_QUEUE[key_index][TempQ_index])
            for CapaQ_index in range(len(CAPACITY_QUEUE[key_index])):
                CapaAddr = GetAndIncrease_Addr(key_index, 'Capacity')
                sheet_Capacity.write(CapaAddr, CAPACITY_QUEUE[key_index][CapaQ_index])
            for VoltQ_index in range(len(VOLTAGE_QUEUE[key_index])):
                VoltAddr = GetAndIncrease_Addr(key_index, 'Voltage') #傳入key值回傳該key於該sheet的現在寫入位址並將位址地增加1
                sheet_Voltage.write(VoltAddr, VOLTAGE_QUEUE[key_index][VoltQ_index])
#寫入該值 到該key的該位址
        print("Excel file write end.\n")
    #else:
        #pass


write_to_excel()函式就是xlsxwriter的使用技巧,其中會呼叫自創函式GetAndIncrease_Addr 定義如下:




#這個函式就不多解釋了,純粹字串跟list的轉換跟應用
def GetAndIncrease_Addr(key, sheet_name):
    str_ADDR = ''
    NOW_ADDR = ''
    NEW_ADDR = ''
    if sheet_name == "Capacity":
        NOW_ADDR = CAPACITY_SHEET_ADDR[key]
    elif sheet_name == "Temperture":
        NOW_ADDR = TEMPERTURE_SHEET_ADDR[key]
    elif sheet_name == "Voltage":
        NOW_ADDR = VOLTAGE_SHEET_ADDR[key]
    ADDR_header_temp = NOW_ADDR[0]
    ADDR_header = ADDR_header_temp
    sNOW_ADDR = NOW_ADDR.strip(ADDR_header_temp)
    iNEW_ADDR = int(sNOW_ADDR) + 1
    if sheet_name == "Capacity":
        CAPACITY_SHEET_ADDR[key] = ADDR_header + str(iNEW_ADDR)
    elif sheet_name == "Temperture":
        TEMPERTURE_SHEET_ADDR[key] = ADDR_header + str(iNEW_ADDR)
    elif sheet_name == "Voltage":
        VOLTAGE_SHEET_ADDR[key] = ADDR_header + str(iNEW_ADDR)
    else:
        print("Can't mapping any sheet name.\n")
    print("NOW_ADDR: " + str(NOW_ADDR))
    return NOW_ADDR







[IoT上層應用] Python 網路爬蟲與資料分析 應用BeautiSoup

[語言工具箱]Python字串、串列、字典、print、與時間格式的處理

字串處理:

2017/8/8 更新

擷取字串片段
轉載自 : http://snowdaily.pixnet.net/blog/post/81181319-python-%E6%93%B7%E5%8F%96%E5%AD%97%E4%B8%B2%E7%89%87%E6%AE%B5


abc = "This is a string"
print abc[5:]   #從第五個到最後  結果為: is a string
print abc[:5]   #從一開始到第五個  結果為: This
print abc[5:7]  #從第五個到第七個(去頭去尾) 結果為: is
此外,用法類似陣列的存取-abc被隱含轉換為字串陣列(串列)

========================================================


字串分為單引號 '  跟雙引號 " ,建議習慣用雙引號,避免特殊字元衝突!!!

"a" in AAA : 檢查a字串有沒有在AAA字串變數裡面出現,有的話回傳True.

大寫字串轉小寫:
abc = "ABCDE"
abc.lower() #字串ABCDE轉成小寫=> abcde


字串相加:
abc="123"
xyz="456"
hjk = abc[1]+xyz[1]
print(hjk) #會印出 "25" ,若要轉int可用int(hjk)

印出字串長度:
abc = "abcde
print(len(abc))   #字串長度 => 5

字串數字轉換:
int("111")  #字串111轉數字=>111
int(float("11.1")) #字串11.1轉浮點數=> 11.1 再馬上轉成 int => 11

=================================================================
串列(有順序):

在python中沒有所謂的陣列只有list(串列)與tuple
list使用方法
list=[] #宣告一個空陣列,名稱為list
串列可以塞任何東西 thread , string , int , float 甚至連serial物件都能塞,但前提是 只能塞一樣的物件在同一串列
若要像C的多維陣列使用方式來用Python串列的話
我們可以使用下列方法 :
a = ['1','2','3']
b = ['1','2','3']
c = [a,b]

若要列印a的第一個元素'1'的話,可以用print(str(c[0][0]))來顯示
就會印出'1'了

Max : max(list) #回傳串列中最大值

Min : min(list) #回傳串列中最小值

Index : list.index(i) #回傳串列中第一次索引到i值的位置

Length : len(list) #回傳串列的長度

Sum : sum(list) #加總串列

Count : list.count(value) #計算串列中出現某值的次數

Append : list.append(物件) #串列新增

Extend : list.extend(物件) #將物件附加到list 的最後,即擴增。

Insert : list.insert(addr,物件)   #example : list.insert(1,"a") 在位置1插入字串a

Remove : list.remove('a')  #移除串列list中的a值

Sort : 在List中若要排列其中的int元素的話就要使用sort功能,如下例 :
list=[1,2,4,3]

list.sort()
list => 1,2,3,4]
在這邊必須特別提到的
sorted(list)
會變成1,2,3,4
但是如果只是單純使用sorted在呼叫原本的串列
-> list
還是會變回成1,2,4,3

Pop : list.pop[i] #取出list中最後一個數值
Range
count : count 方法 可以計算某值在list出現的次數。


=================================================================
Print

在Python中,print的方式比較像JAVA而非C
然而在Python自己本身卻因為版本的分歧,連print的方式也有了差異
原因在Python在Python3的Unicode的支援度更好,所以用了跟以往Python2不一樣的方式。
例如: 時間格式的處理
1.毫秒數列印:
import datetime

print datetime.datetime.now()
處理結果 : 2016-01-08 11:42:31.804186

2.普通秒數列印:

import time
localtime = time.asctime( time.localtime(time.time()) )
print localtime
處理結果 : Fri Jan  8 09:01:11 2016
3.普通秒數列印的另一種方法
import datetime
datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
'2016-03-03 19:25:45'

或是
>>> import datetime
>>> now = datetime.datetime.now()
>>> print unicode(now.replace(microsecond=0))
2011-11-03 11:19:07

4.印一個日曆
import calendar
cal = calendar.month(2008, 1)
print cal;

處理結果 : 
January 2008
Mo Tu We Th Fr Sa Su
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31