2020年3月15日 星期日

[Python]機器與深度學習重點節錄

Ch1認識人工智慧

手寫
語音
電腦視覺
專家系統
自然語言處理
電腦遊戲
智慧機器人

機器學習處理常見 分類問題 & 回歸問題
分類 : 垃圾郵件
回歸 : 預測銷售

機器學習實務上解決五種問題 :
1.分類 : 二元分類、多元分類
2.異常值判斷 : 偵測異常情況
3.預測性分析 : 迴歸
4.分群 : 找到相似度並分析
5.協助決策 : 決定下一步 ex. Alpha Go.

機器學習種類
1.監督式學習  需要給標準答案
分類 : 是非題與分級
迴歸 : 預測
2.非監督是學習 : 分群。
3.半監督式學習 : 透過少量的有標籤資料增加分群正確度。
4.強化學習 : 無明確答案,需要依據資訊改變策略。

===============================================================
Ch2 建構TensorFlow與Keras開發環境

1.python -m pip install -U tensorflow
2.python -m pip install -U keras
3.python -m pip install --upgrade numpy

IDE選擇
Spyder / Jupyter Notebook
運行環境  nVIDIA GTX 1060 6GB顯卡 / Google Colaboratory雲端服務

Google Colaboratory => 到google drive新增 更多裏面去新增應用程式服務
開啟GPU設定 Runtime -> change runtime type



















選擇GPU















使用colaboratory 掛載 google drive外部檔案
from google.colab import drive
drive.mount("/content/drive")











透過授權允許存取google drive底下的其他檔案 如.csv等等
接著透過anaconda prompt部屬keras虛擬環境
conda create --name keras anaconda

conda env remove --name keras //刪除環境

conda env list //檢查目前anaconda環境
activate keras //啟動keras













最後使用命令conda list可以瀏覽安裝清單
==================================================================
Ch3深度學習理論基礎

人工智慧包含 機器學習 包含深度學習 => 故 深度學習是機器學習的子集合

http://playground.tensorflow.org/


圖形結構 有包含頂點與邊線 其中又依照邊線有無方向性分為無方向性圖形與方向性圖形

若路徑有數值則為加權圖形,此外有方向性可行程迴圈稱為方向性循環圖 沒有迴圈則為方向性非循環圖

微分與偏微分
 輸入(樹突) =>細胞核(神經元)=> 輸出(軸突)

人工神經元透過 判斷 輸入*權重 加總是否大於閥值來決定是否輸出為1或0
>= 閥值 => 輸出1;反之 輸出0

ANNs 類神經網路 一種泛稱其中包含 多層感知器MLP、卷積神經網路CNN、循環神經網路RNN

多層感知器(Multilayer Perceptron, MLP) : http://playground.tensorflow.org/就是典型的MLP也稱為前饋神經網路(Feedforward Neural Network, FNN) 是單向多層的傳統類神經網路
輸入資料->輸入層->隱藏層->...->隱藏層->輸出層->輸出資料
多層感知器是神經網路,若隱藏層超過一層(四層的神經網路稱為深度學習)

卷積神經網路(Convolutional Neural Network, CNN) : 專門處理影像辨識 如 分類圖片、人臉與手寫辨識等的模擬人腦視覺處理區的神經網路,也是前饋神經網路的一種,但層次上不同
輸入資料->輸入層->卷積層->池化層->...卷積層->池化層->全連接層->輸出層->輸出資料

循環神經網路(Recurrent Neural Network, RNN) : 具有短期記憶 處理聲音語言與影片等序列資料的神經網路,實務上被改良的LSTM與GRU取代
輸入資料->輸入層->隱藏層->循環隱藏->輸出層->輸出資料

張量 維度數 = 軸數 = 等級(Rank)
0D 純量值
1D一維陣列
2D二維陣列
3D三個維度的三維陣列 or  一維的矩陣陣列  加上時間間距特性
4D 四維陣列 真實特徵資料圖片   圖片集等 就是用4D

import numpy as np

x = np.ndim() //取得軸數
x = np.shap() //取得形狀
+ - * / 直接使用
b= a.dot(s) 點積運算

============================================================
Ch4多層感知器

線性可分割與線性不可分割問題須理解

神經元又稱感知器
回歸問題使用一個神經元
二元分類問題 使用一個或兩個神經元
多元分類問題 看幾類是幾個 => 數字0~9 是10個

層數與神經元數量建議
隱藏層神經元數量為輸入層到輸出層之間
神經元數量是 輸入層2/3 加上輸出層的數量
隱藏層的神經元數量少於兩倍輸入層的神經元數量

監督學習有真實目標值(標準答案)又稱標籤,可以透過差異(損失分數)去調整權重來達到越來越準確的優化

神經網路訓練迴圈分為正向傳播 評估損失 反向傳播
正向傳播 : 計算預測值
評估損失 : 真實目標比較 算出損失
反向傳播 : 計算每一層的錯誤比例,用梯度下降法更新權重‧優化器使用反向傳播計算每一層權重需要分擔損失的梯度

sigmoid會有函數微分只有1/4 若神經網路反向傳播即多個1/4相乘 將會趨近於0造成梯度消失

(傳不到頭)

避免梯度消失問題可以使用ReLU 即輸入小於0時輸出為0;大於0則為線性函數

迴歸問題使用均方誤差
分類問題使用交叉鏑


2020年3月12日 星期四

[Python] 網路爬蟲學習重點節錄

選擇用書Python網路爬蟲與資料視覺化應用實務(旗標出版社)
Request

import requests

requests.get參數
r = requests.get(url , timeout=0.3) //設定time out
r = requests.get(url, cookies={"over18": "1"}) 透過cookies儲存超過18歲 來通過訪問ptt
nextPg = response.xpath(xpath)
url = "http://www.google.com"
timeout = 0.3
'maxResult' : 5,
headers=url_headers


例外處理 :
RequestException 請求錯誤
HTTPError 不合法回應
ConnectionError 連線錯誤
Timeout 逾時
TooManyRedirects 超過轉址值

bs4(BeautifulSoup) + request混合使用


from bs4 import BeautifulSoup
import requests

r = requests.get("http://www.google.com")
soup = BeautifulSoup(r.text, "lxml")
print(soup)

若soup要寫入檔案必須格式化 需要呼叫
prettify()
範例 :
fp = open ("xxx.txt", "w", encoding="utf8")
fp.write(soup.prettify())
print("writting")
fp.close()

============================================================
find()

find() 尋找單一條件
find_all()遍尋整個HTML網頁

find_all()加入限制條件 = >
soup.find_all("tag", class_name="class_name", limit=limit_num )
(tag, id, limit=)

============================================================
Ch4
Select()

BeautifulSoup使用select與select_one
select() 是清單式列出條件符合結果
select_one()是只列一個
css selector使用nth-of-type因此"nth-" 須改寫成=>nth-of-type
如tag.select("div:nth-of-type(3)")

============================================================
Ch5
遍歷祖先兄弟子孫

tag.content與tag.children 都可以取得子標籤
並透過for chile in tag.descendants 取得之下的所有子孫標籤
for tag in tag_ui chile //for子孫標籤
for tag in tag_ui.parent //for祖先標籤

next_sibling 兄弟標籤走訪
previous_sibling


find_previous_sibling() //找上一個兄弟(此函數會自動跳過NavigableString物件)
find_next_sibling() //找下一個兄弟(此函數會自動跳過NavigableString物件)

走訪上下元素
next_element //下一個元素
previous_elements //上一個元素
用法
next_tag = tag.next_element
print(type(next_tag), next_tag.name)

===========================================================
修改
修改僅修改python物件樹並不會修改網頁原始碼
tag.string = "str_value" //修改
del tag["tag_element"] //刪除
new_tag = tag.new_tag("tag's context")  //新增1
tag.append(new_tag) //新增2
insert_before  //插入在xxx之前
insert_after  //插入在xxx之後

Ch5-4 CSV & Json存取
寫入CSV
with open (csv_file, 'w+', newline="")as fp:
writer = csv.writer(fp)
writer =.writerow(["Data1","Data2","Data3"]) //建立Excel檔Data1~Data3的欄位頭

Json
j_str = json.dump(json_data)  //json_data字典轉j_str資料字串
json_data2 = json.loads(j_str) //j_str資料字串轉json_data2字典

j_file = "jfile.json"
with open(j_file, 'r') as fp:  //讀取j_file
json.dump(data, fp) 讀data寫入至fp

Ch5-5載圖
response = request.get(url, stream=True)
with open (path, 'wb') as fp:
  for chunk in response:
     fp.write(chunk)

或用urllib.request.urlopen(url)   開啟下載   //較有效率考量

===========================================================
Ch6 XPath 與 lxml 應用
from lxml import html


找到tag中的資源網址後點三個點點左鍵 copy... XPath 如下圖:










tag_img = tree.xpath("/html/body/section[2]/table/tbody/tr[21]/td[1]/a/img")[0]
print(tag_img.attrib["src"])

=>https://www.flag.com.tw/assets/img/bookpic/F4473.jpg

6-4XPath 基本語法 軸::節點測試[謂詞]
* : 萬用字元,表所有符合元素和屬性節點
軸 : 開始點 (軸定義請詳閱)
節點測試 : 此軸符合的節點有哪些
謂詞Predicates : 進一步過濾條件
以書中範例/child::library/child::book[2]/child::author
/child::library 代表根後子節點為library
/child::book[2] 子節點為book的第二筆
/child::author 子節點為author

XPath Helper點選 按住shift 把想查詢的地方選取 即可完成




















====================================================================
Ch7 Selenium

安裝selenium    python -m pip install -U selenium

並安裝chrome driver : https://sites.google.com/a/chromium.org/chromedriver/downloads

from selenium import webdriver //import webdriver

driver = webdriver.Chrome("./chromedriver")

driver.get(url)
tag = driver.fine_element_by_tag_name("tag")
soup = BeautifulSoup(driver.page_source, "lxml")

find_element_by_id()
find_element_by_name()
find_element_by_xpath()
find_element_by_link_text()
find_element_by_partial_link_text()
find_element_by_tag_name()
find_element_by_class_name()
find_element_by_css_selector()

執行google搜尋
keyword = driver.find_element_by_css_selector("#lst-ib")
keyword.send_keys("search term")
keyword.send_keys(keys.ENTER);

Keys 按鍵常數清單
https://www.selenium.dev/selenium/docs/api/java/org/openqa/selenium/Keys.html


Selenium Action Chains 產生一系列網頁自動操作
click()  //點選元素
click_and_hold() //按住左鍵
context_click() //按住右鍵
double_click() //按兩下元素
move_to_element() //移到元素中間
key_up() //放開某鍵
key_down() //按下某鍵
perform() //執行所有儲存動作
semd_keys()  //送出按鍵至目前的元素
release() //鬆開滑鼠按鍵

act = ActionChains(driver)
act.move_to_element(ele)
act.click(eee)
act.perform()

===============================================================
Ch8

Anaconda3/Anaconda Prompt執行conda install -c conda-forge scrapy

===============================================================
Ch9

爬蟲程式的選擇
爬取數頁網頁 => BeautifulSoup
動態網頁爬取 => Selenium
整個Web網站的大量資料 => Scrapy框架

9-1透過urljoin搭配.format來對網址序列化
例如 :
catalog = ["2317", "3018", "2308"]
for i in catalog
url = urljoin("https://tw.stock.yahoo.com/q/q?s={0}".format(i)
print(url)

===============================================================
Ch10
SQL語句
SELECT * FROM
WHERE 條件 LIKE 其中LIKE有包含的意思  %a% 包含a的字串

import pymysql
db = pymysql.connect("localhost", "root", "", "mybooks", charset="utf8")
cursor = db.cursor() //取出
cursor.execute("SELECT * FROM books") //取出

sql = """INSERT abc (......)VALUES(......)""" //存入
try:
cursor.execute(sql)//執行
db.commit()//確定送出


====================================================================
歐萊禮補充
Ch1
from urllib.request import urlopen
html = urlopen("http://xxx/xxx.html")
print(html.read())
python2.x => urllib2
python3.x => urllib

Ch2 from urllib.request import urlopen
from bs4 import BeautifulSoup
html = urlopen("http://xxx.xxx/xxx.html")
bsObj = BeautifulSoup(html)
用findAll函式
nameList = bsObj.findAll("span", {"class":"green"})
for name in nameList:
    print(name.get_text())

.get_text 會從文件裡過濾掉所有標籤 回傳紙包含文字內容的字串
.get_text通常都是最後一個步驟 通常是列印儲存或處理最終資料時才做
通常在還沒到最後處理前 盡可能保有標籤資訊
class 是python保留字 所以直接寫會引發錯誤
可以使用bs解法 class_ 或 將class包在引號裡 => .findAll("span", {"class":"green"})

child
for child in bsObj.find("table", {"id":"giftList"}).children:
print(child)

RE 正規表達式
aa*
bbbbb 連續五個b
(cc)* 一對c可出現任何次數
@ 必須出現@ 而且必須出現一次
[A-Za-z]+ 只能使用字母 至少必須有一個字母


RegexPal : http://regexpal.com/


bs + 正規表達式範例 :
from bs4 import BeautifulSoup
html = urlopen("http://xxx.xxx/xxx.html")
bsObj = BeautifulSoup(html)
imges = bsObj.findAll("img", {"src" : re.compile("\.\./img\/gifts/img.*\.jpg")})
for imge im imges:
      print(imge["src"])

ch3
python遞迴深度限制是1000次 像wiki連結網路大的會當掉

重導分為
Server-side重導與Client-side重導
Server-side重導 => python 3.x的urllib會自動處理
Client-side重導 => ch10 使用java script或html達到

Scrapy 五個log紀錄層級
CRITICAL
ERROR
WARNING
DEBUG
INFO
ex. 使用LOG_LEVEL = 'ERROR'
將LOG記錄儲存到特定的檔案
scrapy crawl article -s LOG_FILE=wiki.log

ch4使用API
方法
GET => 請網站主機把某某資料拿給你
POST => 填寫表單傳送資料的動作 每次登入網站會用POST送出名稱與密碼 像是告訴server請將這份資料存到資料庫
PUT => 用來更新物件或資訊
DELETE => 像Server送出刪除資料要求


ch6讀取文件
讀取docx => 以open office xml標準為基礎的office word等工具
from zipfile import Zipfile
from urllib.request import urloprn
from io.import BytesIO

wordFile = urlopen("http://xxx.com/pages/xxx.docx").read()
wordFile = BytesIO(wordFile)
document = ZipFile(wordFile)
xml_content = document.read('word/document.xml')
print(xml_content.decode('utf-8'))

wordObj = BeautifulSoup(xml_content.decode('utf-8'))
textStrings = wordObj.findAll("w:t")
for textElem in textStrings:
      print(textElem.text)

Ch11 影像處理與文字辨識 p.175
透過 import subprocess
引入Tesseract
來做辨識
p = subprocess.Popen(["tesseract", "captcha.jpg", "captcha"]), stdout = subprovess.PIPE,stderr=subprocess.PIPE)
p.wait()
f = open("captcha.txt", "r")


ch13以Scrapers測試你的網站
driver.get_screenshot_as_file("tmp/pythonscraping.png")


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

2017年7月24日 星期一

[語言工具箱] C Linux queue.h之TAILQ序列實作

make_i2c_message->產生訊息並塞到queue.

i2c_tx_check(每300ms檢查一次) -> send_rf_cmd() ->

=============================================================
infoManager.c

static timer g_sendi2c_timer;

TAILQ_HEAD(i2c_tx_queue, i2c_tx_message);
struct i2c_tx_queue *tx_q = NULL;
#define RF_WKUP_MAIN 129//ENET0_MDIO bank4 pin1



int send_rf_cmd(struct i2c_tx_message *msg)
{
    int ret = 1;
    switch(msg->id)
    {
             .....中間略過......
    }
    return ret;
}

.................中間略過.................

void* i2c_tx_check(void* unused)
{
    int ret = 0;
    uint32_t fob_status;
    struct i2c_tx_message *m2 = NULL;
    ret = gpio_get_value(RF_WKUP_MAIN, &fob_status);
    //printf("[Gerald] RF_WKUP_MAIN = %d\n", fob_status);

    if(ret > 0)//errno
    {
        IM_DBG_ERROR("read RF_WKUP_MAIN failed, ret = %d", ret);
        return;
    }
    if((!TAILQ_EMPTY(tx_q)) && (fob_status == 1))//high: ready; low: busy
    {
        m2 = TAILQ_FIRST(tx_q);
        ret = send_rf_cmd(m2);
        TAILQ_REMOVE(tx_q, m2, node);
        free(m2);
    }
}


void start_checker_timer()
 {
    .................中間略過.................
    timer_setup(&g_sendi2c_timer);
     .................中間略過.................
    g_sendi2c_timer.set_timer(&g_sendi2c_timer, 300, true, i2c_tx_check, NULL);
 }


void stop_checker_timer()
 {
    .................中間略過.................
    g_sendi2c_timer.cancel(&g_sendi2c_timer);
 }

void init_i2c_tx_queue()
{
    tx_q = malloc(sizeof(*tx_q));
    TAILQ_INIT(tx_q);
    gpio_export(RF_WKUP_MAIN);
    gpio_dir_in(RF_WKUP_MAIN);
}

void uninit_i2c_tx_queue()
{
    free(tx_q);
}

void make_i2c_message(enum rf_command_table id, char *cmd)
{
    struct i2c_tx_message *m1 = NULL;
    m1 = calloc(1, sizeof(*m1));
    if(m1 == NULL)
    {
        IM_DBG_ERROR("Can not allocate i2c cmd\n");
    }
    else
    {
        m1->id = id;
        m1->cmd = cmd;
        TAILQ_INSERT_TAIL(tx_q, m1, node);
        DKEY_BMW_PROFILE_LOG("cmd_id = %d, value = %s", m1->id, m1->cmd);
    }
}



void initInfoManager() {
      .................中間略過.................
    infoMgr->make_i2c_message = make_i2c_message;
     .................中間略過.................
    init_i2c_tx_queue();
 }

void uninitInfoManager() {
     .................中間略過.................
    uninit_i2c_tx_queue();
     .................中間略過.................
}
==============================================================
infoManager.h

#include <sys/queue.h>


enum rf_command_table {
    MASTER_STATE             = 1,
    ACCESS                   = 2,
    WINDOW                   = 3,
    MISCELLANEOUS            = 4,
    AUTO_DRIVING             = 5,
    VEHICLE_FACILITY_CONTROL = 6,
};

struct i2c_tx_message
{
    enum rf_command_table id;
    char *cmd;
    TAILQ_ENTRY(i2c_tx_message) node;
};

 typedef struct infoManager_s {
     .................中間略過.................
    void (*make_i2c_message)();

 } infoManager;


void add_language_change_event_notify(enum im_evnet_category_t category, int eve
 .................中間略過.................
int send_rf_cmd(struct i2c_tx_message *msg);
========================================================

結論 :























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