目前分類:Python 程式設計 (52)

瀏覽方式: 標題列表 簡短摘要

這篇是使用wxPython 模組去記錄視窗程式設計

目前使用的環境:windows 7、Portable Python 2.7.6.1、wxPython 3.0請參考下面的範例說明

Graphical User Interface(GUI) 圖形使用者介面

通常來講,一個視窗的組成類似積木的堆疊,主要包括「Frame」(框架)、「Panel」(面板)、「Controls」(控制項)

三個主要部分。以下以 Windows 內建的「超級終端機」為例,來說明視窗的各主要零件。

視窗 的底層畫板-Frame(框架)

Frame 是一個視窗的最底層,所有的視窗元件都是建構在 Frame 裡面,而一般常見的 Frame 中,會有「MenuBar」(選單列)、「ToolBar」(工具列)、「StatusBar」(狀態列)和「Panel」(面版)。以下簡單說明各個部分。

  • MenuBar(選單列):為下拉式選單,通常所有應用程式的功能,都可在選單列中找到。

  • ToolBar(工具列):將各種常用的功能,以圖示的方式展現出來,方便取用。

  • StatusBar(狀態列):用來顯示應用程式的狀態訊息。

  • Panel(面板):用來配置視窗操作時,需要使用的各種 Controls(控制項)。

組合 各種元素的畫布-Panel(面板)

前面提到,Panel 是用來放置各種 Controls(控制項)的地方。

而 Controls(控制項)指的就是各種視窗控制項,像這裡看到的有「Button(按鈕)」、「TextCtrl(文字方塊)」。

原料 -Controls(控制項)

Controls(控制項)除了前面提到的 Button(按鈕)、TextCtrl(文字方塊)以外,還包括許多大家常見的元件。

 Button (按鈕)
TextCtrl (文字方塊控制項)
CheckBox (核取方塊控制項)
StaticText (靜態文字控制項)
ListBox (清單控制項)
RadioBox (選取按鈕控制項)

#---------------------------------------------------
第一個Hello World 的視窗程式設計-1

# -*- coding: big5 -*-
import wx

class MyApp(wx.App):  
    def OnInit(self):
        frame=wx.Frame(parent=None,title="早安Hello,wxPython!",size=(320,240))
        frame.Show()
        return True

app=MyApp()
app.MainLoop()

(1)#建立 MyApp類別並繼承wx.App類別
(2)#overload OnInit函數,OnInit是視窗初始化的一部份
(3)#並且建立一個wx.Frame,parent預設為None;如果不為None則Frame會一直在最上層視窗
    #另外設定frame的t視窗標題title,視窗的長寬size
(4)#顯示視窗
(5)#通常在OnInit函數的回傳值是True
(6) #執行主程式

#----------------------------------------

第一個Hello World 的視窗程式設計-2

#<path_to_python>
# -*- coding: big5 -*-
import wx

app = wx.App(False)  # Create a new app, don't redirect stdout/stderr to a window.
frame = wx.Frame(None, wx.ID_ANY, "Hello World") # A Frame is a top-level window.
frame.Show(True)     # Show the frame.
app.MainLoop()

#-------------------------

第二個程式在表單(frame)裡面加入文字檔
注意: 每個視窗都有一個確認ID,而這個ID有三種方式給與
(1) 系統自動給與  (設定為-1)
(2) 使用wx標準的ID,例如: wx.ID_ANY, wx.ID_CANCEL, wx.ID_DELETE, wx.ID_SAVE, wx.ID_EXIT, wx.ID_STOP, and wx.ID_NEW 
(3)利用wx.NewId()得到自己的ID
 

# -*- coding: big5 -*-
import wx

class HelloFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, -1, "HelloFrame", size=(200, 100))
        panel = wx.Panel(self, -1)  #初始化frame
        wx.StaticText(panel, -1, "Hello World", pos=(60, 25)) #設定文字

if __name__ == '__main__':
    app = wx.PySimpleApp()  #建立simple app
    frame = HelloFrame()       #產生自訂frame
    frame.Show(True)            #顯示frame
    app.MainLoop()                #執行app

class:定義一個Hello Frame class,它繼承wx.Frame
def:定義函數
    __init__:建構函數/初始化 
    wx.Frame:__init__是wx.Frame初始化/建構的動作,需要傳入parent、id、title、pos、size、style、name等參數。 
       parent:當前視窗的父視窗。如果當前視窗是top-level window的話,則parent=None,如果不是,則值為所屬frame的名字。 
       id:視窗編號。預設為-1,則係統自動給他分配一個編號1。 
       title:視窗標題,即Caption。預設為空字串。 
       pos:視窗位置坐標。預設為(-1,-1),位置由系統決定。 
       size:視窗大小。預設為(-1,-1),大小由系統決定。 
       style:視窗樣式。預設為DEFAULT_FRAME_STYLE。 
       name:視窗名稱。 
wx.Panel:面板是最基本的界面工具集合,用來在視窗中用來配置其他Widgets,相同於wx.Frame都需要給個id,在此使用-1,讓系統分配編號。 
wx,StaticText:靜態文字

app = wx.PySimpleApp是建立起動應用程式。 
frame = HelloFrame()是建立我們所自訂的視窗框架。
frame.Show:顯示視窗
app.MainLoop:執行應用程式。 

#----------------------------

第三個程式在表單(frame)裡面加入按鈕與設定事件處理

# -*- coding: big5 -*-
#-------------------------------------------------------------------------------
# Author: Stanley
#-------------------------------------------------------------------------------
import wx
class MyApp(wx.App):
  def OnInit(self):
   frame=wx.Frame(parent=None,title="按鈕視窗",pos=(100,150),size=(320,240))
   frame.Show()
   self.SetTopWindow(frame)
   return True

class MyFrame(wx.Frame):
    def __init__(self,title,pos,size):
       wx.Frame.__init__(self,None,-1,title,pos,size)
       panel=wx.Panel(self)
       button=wx.Button(panel,label="按鈕1",pos=(25,25),size=(60,25))
       self.Bind(wx.EVT_CLOSE,self.OnCloseWin)
       self.Bind(wx.EVT_BUTTON,self.OnClick,button)
    def OnClick(self,event):
         wx.MessageBox("你按了按鈕","提示訊息")
    def OnCloseWin(self,event):
         dlg=wx.MessageDialog(None,"確定要關閉程式?","提示訊息",wx.YES_NO)
         if dlg.ShowModal()==wx.ID_YES:
           self.Destroy()

def main():
    app=MyApp()
    app.MainLoop()

if __name__=="__main__":
    main()

  #新增一個panel
  #新增一個按鈕並把它加到panel裡面
  #建立事件監聽
  #按鈕關閉
  #按鈕按下    
       
  #定義按鈕按下的函數    
    def OnClick(self,event):
        wx.MessageBox("你按了按鈕","提示訊息")
      
  #定義按下關閉視窗(右上X)的函數
    def OnCloseWin(self,event):
        dlg=wx.MessageDialog(None,"確定要關閉程式?","提示訊息",wx.YES_NO)        
        #按下YES才會關閉視窗

 

第四個程式在表單(frame)裡面加入配置視窗元件

# -*- coding: big5 -*-
#-------------------------------------------------------------------------------
# Author: Stanley
#-------------------------------------------------------------------------------
import wx,string
class MySalgar(wx.Frame):
  def __init__(self):
      wx.Frame.__init__(self, parent=None, title=u"薪資試算程式", size=(250,200))
      panel = wx.Panel(self)
#配置視窗元件 -- 開始 --
      wx.StaticText(parent=panel,label=u"工作幾年?",pos=(10,10))
      self.a = wx.TextCtrl(parent=panel,pos=(100,10))
      wx.StaticText(parent=panel,label=u"一個月多少錢?",pos=(10,50))
      self.b = wx.TextCtrl(parent=panel,pos=(100,50))
      self.btn = wx.Button(parent=panel,label=u"結算薪資",pos=(10,100))
      self.message1 = wx.StaticText(parent=panel,pos=(10,130))
      self.message2 = wx.StaticText(parent=panel,pos=(10,150))
#配置視窗元件 -- 結束 --
if __name__ == '__main__':
  app = wx.PySimpleApp()
  frame = MySalgar()
  frame.Show()
  app.MainLoop()

第五個程式在表單(frame)裡面加入配置視窗元件與設定事件處理

# -*- coding: big5 -*-
#-------------------------------------------------------------------------------
# Author: Stanley
#-------------------------------------------------------------------------------
import wx,string
class MySalgar(wx.Frame):
  def __init__(self):
    wx.Frame.__init__(self,parent=None,title=u"薪資試算程式",size=(250,200))
    panel = wx.Panel(self)
    wx.StaticText(parent=panel,label=u"工作幾年?",pos=(10,10))
    self.a = wx.TextCtrl(parent=panel,pos=(100,10))
    wx.StaticText(parent=panel,label=u"一個月多少錢?",pos=(10,50))
    self.b = wx.TextCtrl(parent=panel,pos=(100,50))
    self.btn = wx.Button(parent=panel,label=u"結算薪資",pos=(10,100))
#新增 BtnClick 事件 -- 開始 --
    self.Bind(wx.EVT_BUTTON,self.BtnClick,self.btn)
#新增 BtnClick 事件 -- 結束 --
    self.message1 = wx.StaticText(parent=panel,pos=(10,130))
    self.message2 = wx.StaticText(parent=panel,pos=(10,150))
#撰寫 BtnClick 事件函式 -- 開始 --
  def BtnClick(self,event):
    a = self.a.GetValue()
    a = string.atoi(a)
    b = self.b.GetValue()
    b = string.atoi(b)
    c = b * 12 * a
    d = c /(365 * a)
    message1Str = u'您工作 '+str(a)+u' 年可以獲得 '+str(c)+u' 元'
    message2Str = u'平均每日獲得 '+str(d)+u' 元'
    self.message1.SetLabel(message1Str)
    self.message2.SetLabel(message2Str)
#撰寫 BtnClick 事件函式 -- 結束 --
if __name__ == '__main__':
    app = wx.PySimpleApp()
    frame = MySalgar()
    frame.Show()
    app.MainLoop()

有這5個根本程式架構,讀者就可以依文件上的元件說明開發自己的專案程式。

回主目錄

 

 

 

  •  
  •  
  •  

 

 

  •  
文章標籤

stanley 發表在 痞客邦 留言(0) 人氣()

如果你正在學習如何操控Excel,小編是認為利用openpyxl的方式較簡潔,直覺和簡單化,不過利用Win32Com也是可以的

請參考下面的範例說明

#使用Python的 PyWin32 和 the win32com library 去操作Excel 的圖形 
# ExcelChart
# Creates a Microsoft Excel Chart given a data range
# and whole bunch of other parameters

# -*- coding: big5 -*- 
import win32com.client
from win32com.client import constants

#定義一個Excel應用程式 Class
# ExcelApp
class ExcelApp:
    def __init__(self):
        self.excel = win32com.client.Dispatch("Excel.Application")
        self.workbooks = []
        self.SetDefaultSheetNum(1)
    def Show(self):
        self.excel.Visible = 1
    def Hide(self):
        self.excel.Visible = 0
    def Quit(self):
        for wkb in self.workbooks:
            wkb.Close()
        self.excel.Quit()
    def SetDefaultSheetNum(self, numSheets):
        self.excel.SheetsInNewWorkbook = numSheets
    def AddWorkbook(self, filename):
        workbook = ExcelWorkbook(self.excel, filename)
        self.workbooks.append(workbook)
        return workbook

#定義一個Excel Workbook Class
# ExcelWorkbook
class ExcelWorkbook:
    def __init__(self, excel, filename):
        self.filename = filename
        self.excel = excel
        self.workbook = self.excel.Workbooks.Add()
        self.worksheets = {}
    def AddWorksheet(self, name):
        worksheet = ExcelWorksheet(self.excel, self.workbook, name)
        self.worksheets[name] = worksheet
        return worksheet
    def AddChart(self, name, afterSheet):
        chart = ExcelChart(self.excel, self.workbook, name, afterSheet)
        self.worksheets[name] = chart
        return chart
    def Save(self):
        self.workbook.SaveAs(self.filename)
    def Close(self):      
        self.worksheets = {}
        self.workbook.Close()
    def SetAuthor(self, author):
        self.workbook.Author = author

#定義一個Excel WorkSheet Class
# ExcelWorksheet
class ExcelWorksheet:
    def __init__(self, excel, workbook, sheetname):
        self.sheetname = sheetname
        self.excel = excel
        self.workbook = workbook
        self.worksheet = self.workbook.Worksheets.Add()
        self.worksheet.Name = sheetname
    def Activate(self):
        self.worksheet.Activate()
    def SetCell(self, row, col, value):
        self.worksheet.Cells(row,col).Value = value
    def GetCell(self, row, col):
        return self.worksheet.Cells(row,col).Value
    def SetFont(self, row, col, font, size):
        self.worksheet.Cells(row,col).Font.Name = font
        self.worksheet.Cells(row,col).Font.Size = size
    def GetFont(self, row, col):
        font = self.worksheet.Cells(row,col).Font.Name
        size = self.worksheet.Cells(row,col).Font.Size
        return (font, size)

#定義一個Chart Class 
class ExcelChart:
    def __init__(self, excel, workbook, chartname, afterSheet):
        self.chartname = chartname
        self.excel = excel
        self.workbook = workbook
        self.chartname = chartname
        self.afterSheet = afterSheet

    def SetTitle(self, chartTitle):
        self.chartTitle = chartTitle

    def SetType(self, chartType):
        self.chartType = chartType

    def SetSource(self, chartSource):
        self.chartSource = chartSource

    def SetPlotBy(self, plotBy):
        self.plotBy = plotBy

    def SetCategoryLabels(self, numCategoryLabels):
        self.numCategoryLabels = numCategoryLabels

    def SetSeriesLabels(self, numSeriesLabels):
        self.numSeriesLabels = numSeriesLabels

    def SetCategoryTitle(self, categoryTitle):
        self.categoryTitle = categoryTitle

    def SetValueTitle(self, valueTitle):
        self.valueTitle = valueTitle

    def CreateChart(self):
        self.chart = self.workbook.Charts.Add(After=self.afterSheet)
        self.chart.ChartWizard(Gallery=win32com.client.constants.xlColumn, \
                               CategoryLabels=1, \
                               SeriesLabels=1, \
                               CategoryTitle = self.categoryTitle, \
                               ValueTitle = self.valueTitle, \
                               PlotBy=self.plotBy, \
                               Title=self.chartTitle)
        self.chart.SetSourceData(self.chartSource, self.plotBy)
        #self.chart.HasAxis = (constants.xlCategory, constants.xlPrimary)
        #self.chart.Axes(constants.xlCategory).HasTitle = 1
        #self.chart.Axes(constants.xlCategory).AxisTitle.Text = self.categoryTitle
        #self.chart.Axes(constants.xlValue).HasTitle = 1
        #self.chart.Axes(constants.xlValue).AxisTitle.Text = self.valueTitle
        #self.chart.Axes(constants.xlValue).AxisTitle.Orientation = constants.xlUpward
        #self.chart.PlotBy = self.plotBy 
        #self.chart.Name = self.chartname
        #self.chart.HasTitle = 1
        #self.chart.ChartTitle.Text = self.chartTitle
        #self.chart.HasDataTable = 0
        #self.chart.ChartType = self.chartType 

    def SetLegendPosition(self, legendPosition):
        self.chart.Legend.Position = legendPosition

    def PlotByColumns(self):
        self.chart.PlotBy = constants.xlColumns

    def PlotByRows(self):
        self.chart.PlotBy = constants.xlRows

    def SetCategoryAxisRange(self, minValue, maxValue):
        self.chart.Axes(constants.xlCategory).MinimumScale = minValue
        self.chart.Axes(constants.xlCategory).MaximumScale = maxValue

    def SetValueAxisRange(self, minValue, maxValue):
        self.chart.Axes(constants.xlValue).MinimumScale = minValue
        self.chart.Axes(constants.xlValue).MaximumScale = maxValue

    def ApplyDataLabels(self, dataLabelType):
        self.chart.ApplyDataLabels(dataLabelType)

    def SetBorderLineStyle(self, lineStyle):
        self.chart.PlotArea.Border.LineStyle = lineStyle

    def SetInteriorStyle(self, interiorStyle):
        self.chart.PlotArea.Interior.Pattern = interiorStyle

#----- begin main program -----------        
def Main():
    excel = ExcelApp()
    excel.Show()
    
    workbook = excel.AddWorkbook("c:\\tmp\\games1.xlsx")
    
    games = workbook.AddWorksheet("Game Sales")
    accessories = workbook.AddWorksheet("Accessories")
    
    games.Activate()
    
    games.SetFont(1,1,"Arial",18)
    games.SetCell(1,1, "Excel Controlled from Python - Game Sales")
    
    months = ["January", "February", "March"]
    systems = ["Nintendo GameCube", "Sony Playstation 2", "Microsoft XBox"]
    for i in range(len(months)): games.SetCell(3, i+2, months[i])
    for j in range(len(systems)): games.SetCell(4 + j, 1, systems[j])
    
    for i in range(4,6+1):
        for j in range(2,4+1):
            games.SetCell(i,j, i*j)
            
    chart = workbook.AddChart("Gaming Sales Chart", games.worksheet)
    chart.SetTitle("Games Sold by Platform Type per Month")
    chart.SetSource(games.worksheet.Range("A3:D6"))
    chart.SetType(win32com.client.constants.xlColumn)
    chart.SetPlotBy(win32com.client.constants.xlRows)
    chart.SetCategoryTitle("Months")
    chart.SetValueTitle("Sales")
    chart.SetCategoryLabels(1)
    chart.SetSeriesLabels(1)
    chart.CreateChart()
    
    workbook.Save()
    
    excel.Quit()
    
if __name__ == '__main__':
    Main()

注意事項:

1.  如果出現如下的__getattr__    raise AttributeError(a) AttributeError: xlLline 錯誤表示你的電腦並没認識 win32com.client.constancts的常數定義,所以你要到 C:\XX\Portable Python 2.7.6.1\App\lib\site-packages\win32com\client\下執行make.py 

Traceback (most recent call last):
  File "<module1>", line 206, in <module>
  File "<module1>", line 193, in Main
  File "I:\software dictionary\Portable Python 2.7.6.1\App\lib\site-packages\win32com\client\__init__.py", line 170, in __getattr__
    raise AttributeError(a)
AttributeError: xlLLine

2.  執行 make.py 完後會出現一個選項視窗,要選擇EXCEL的type library,執行完後會匯入 Excel 的 type library到你的系統內,產生的訊息如下 

Generating to C:\Users\stanley\AppData\Local\Temp\gen_py\2.7\00020813-0000-0000-C000-000000000046x0x1x7.py
Building definitions from type library...
Generating...
Importing module
Exit code:  0

參考資料

https://gist.github.com/mikepsn/27dd0d768ccede849051

回主目錄

 

文章標籤

stanley 發表在 痞客邦 留言(0) 人氣()

這篇是使用Win32Com 模組去操控Excel, 包括開啓workbook, worksheet 和 cell operations。

如果你正在學習如何操控Excel,小編是認為利用openpyxl的方式較簡潔,直覺和簡單化,不過利用Win32Com也是可以的

請參考下面的範例說明

Open Excel, Add a Workbook

import win32com.client as win32
excel = win32.gencache.EnsureDispatch('Excel.Application')
wb = excel.Workbooks.Add()
wb.SaveAs('c:\\tmp\\add_a_workbook.xlsx')
excel.Application.Quit()

Open an Existing Workbook

import win32com.client as win32
excel = win32.gencache.EnsureDispatch('Excel.Application')
wb = excel.Workbooks.Open('c:\\tmp\\add_a_workbook.xlsx')
excel.Visible = True

Add a Worksheet  (有中文-第一行要加)

# -*- coding: big5 -*-
import win32com.client as win32
excel = win32.gencache.EnsureDispatch('Excel.Application')
wb = excel.Workbooks.Add()
ws = wb.Worksheets.Add()
ws.Name = "圖一"
wb.SaveAs('c:\\tmp\\add_a_worksheet.xlsx')
excel.Application.Quit()

ell operations 

Ranges and Offsets

import win32com.client as win32
excel = win32.gencache.EnsureDispatch('Excel.Application')
wb = excel.Workbooks.Add()
ws = wb.Worksheets.Add()
ws.Name = "MyNewSheet"
ws.Cells(1,1).Value = "Cell A1"
ws.Cells(1,1).Offset(2,4).Value = "Cell D2"
ws.Range("A2").Value = "Cell A2"
ws.Range("A3:B4").Value = "A3:B4"
ws.Range("A6:B7,A9:B10").Value = "A6:B7,A9:B10"
wb.SaveAs('ranges_and_offsets.xlsx')
excel.Application.Quit()

Autofill Cell Contents

import win32com.client as win32
excel = win32.gencache.EnsureDispatch('Excel.Application')
wb = excel.Workbooks.Add()
ws = wb.Worksheets.Add()
ws.Name = "MyNewSheet"
ws.Range("A1").Value = 1
ws.Range("A2").Value = 2
ws.Range("A1:A2").AutoFill(ws.Range("A1:A10"),win32.constants.xlFillDefault)
wb.SaveAs('autofill_cells.xlsx')
excel.Application.Quit()

Cell Color

import win32com.client as win32
excel = win32.gencache.EnsureDispatch('Excel.Application')
wb = excel.Workbooks.Add()
ws = wb.Worksheets.Add()
ws.Name = "MyNewSheet"
for i in range (1,21):
    ws.Cells(i,1).Value = i
    ws.Cells(i,1).Interior.ColorIndex = i
wb.SaveAs('cell_color.xlsx')
excel.Application.Quit()

Column Formatting

import win32com.client as win32
excel = win32.gencache.EnsureDispatch('Excel.Application')
wb = excel.Workbooks.Add()
ws = wb.Worksheets.Add()
ws.Name = "MyNewSheet"
ws.Range("A1:A10").Value = "A"
ws.Range("B1:B10").Value = "This is a very long line of text"
ws.Columns(1).ColumnWidth = 1
ws.Range("B:B").ColumnWidth = 27
wb.SaveAs('column_widths.xlsx')
excel.Application.Quit()

Format Worksheet Cells

import win32com.client as win32
excel = win32.gencache.EnsureDispatch('Excel.Application')
wb = excel.Workbooks.Add()
ws = wb.Worksheets.Add()
ws.Name = "MyNewSheet"

for i,font in enumerate(["Arial","Courier New","Garamond","Georgia","Verdana"]):
    ws.Range(ws.Cells(i+1,1),ws.Cells(i+1,2)).Value = [font,i+i]
    ws.Range(ws.Cells(i+1,1),ws.Cells(i+1,2)).Font.Name = font
    ws.Range(ws.Cells(i+1,1),ws.Cells(i+1,2)).Font.Size = 12+i

ws.Range("A1:A5").HorizontalAlignment = win32.constants.xlRight
ws.Range("B1:B5").NumberFormat = "$###,##0.00"
ws.Columns.AutoFit()
wb.SaveAs('format_cells.xlsx')
excel.Application.Quit()

Setting Row Height

import win32com.client as win32
excel = win32.gencache.EnsureDispatch('Excel.Application')
wb = excel.Workbooks.Add()
ws = wb.Worksheets.Add()
ws.Name = "MyNewSheet"

ws.Range("A1:A2").Value = "1 line"
ws.Range("B1:B2").Value = "Two\nlines"
ws.Range("C1:C2").Value = "Three\nlines\nhere"
ws.Range("D1:D2").Value = "This\nis\nfour\nlines"
ws.Rows(1).RowHeight = 60
ws.Range("2:2").RowHeight = 120
ws.Rows(1).VerticalAlignment = win32.constants.xlCenter
ws.Range("2:2").VerticalAlignment = win32.constants.xlCenter

# Alternately, you can autofit all rows in the worksheet
# ws.Rows.AutoFit()

wb.SaveAs('row_height.xlsx')
excel.Application.Quit())
excel.Application.Quit()

 

參考資料 

http://pythonexcels.com/python-excel-mini-cookbook/

回主目錄

 

 

 

文章標籤

stanley 發表在 痞客邦 留言(0) 人氣()

使用openpyxl 去讀取,寫入,操控Excel的基本設定、表格、圖表

Author: Eric Gazoni, Charlie Clark
Source code: http://bitbucket.org/openpyxl/openpyxl/src
Issues: http://bitbucket.org/openpyxl/openpyxl/issues
Generated: Apr 20, 2017
License: MIT/Expat
Version: 2.4.6

Document: https://openpyxl.readthedocs.io/en/default/

注意,1. openpyxl只支援xlsx格式,舊版的xls格式需要用其他方法去處理。

另外因為EXCEL,windows console 正常顥示中文必須用big5碼,所以編輯,儲存必須用big 5 碼

並且 Python 敘述寫在程式檔案中,執行時,要注意到兩件事:

1. 程式檔案的編碼:若存檔成 big5 碼,則要在程式中的第一行或第二行,告訴 Python 編碼方式

#!/usr/bin/env python

# -*- coding: big5 -*- # Note the first line in the above is for Operating system, the # second line is for Python interpreter

2. 要寫中文字至EXCEL時要做decode 才可正常顥示在EXCEL內。例如: ws4['A1'] = "中文".decode('big5')

3. 最好使用 >>import openpyxl    >>print openpyxl.__version__ 
    確定使用較新版的openpyxl , 太舊的版本無法支援chart 方面的操作但基本操作是可以。
    例如安裝portable Python 2.7.6.1 安裝的OpenPyXL 是1.8.5版,如此在Chart方面會找不到模組。
 
4. Python 與中文處理可參考這篇文章

Working with Pandas and NumPy

openpyxl is able to work with the popular libraries Pandas and NumPy, openpyxl has builtin support for the NumPy types float, integer and boolean. DateTimes are supported using the Pandas’ Timestamp type

File Operations

Saving to a file

wb = Workbook()
wb.save('balances.xlsx')

Loading from a file

from openpyxl import load_workbook
wb2 = load_workbook('test.xlsx')
print wb2.get_sheet_names()
['Sheet2', 'New Title', 'Sheet1']

#------------------------------------------

WorkBook operations 

Write a workbook

from openpyxl import Workbook
from openpyxl.compat import range
from openpyxl.utils import get_column_letter

wb = Workbook()

dest_filename = 'empty_book.xlsx'
ws1 = wb.active

ws1.title = "range names"
for row in range(1, 40):
    ws1.append(range(600))

ws2 = wb.create_sheet(title="Pi")
ws2['F5'] = 3.14

ws3 = wb.create_sheet(title="Data")
data = [
    ['Apples', 10000, 5000, 8000, 6000],
    ['Pears',   2000, 3000, 4000, 5000],
    ['Bananas', 6000, 6000, 6500, 6000],
    ['Oranges',  500,  300,  200,  700],
]

# add column headings. NB. these must be strings
ws3.append(["Fruit", "2011", "2012", "2013", "2014"])
for row in data:
    ws3.append(row)

print(ws3['A10'].value)

wb.save(filename = dest_filename)

Read an existing workbook

from openpyxl import load_workbook
wb = load_workbook(filename = 'empty_book.xlsx')
sheet_ranges = wb['range names']
print(sheet_ranges['A1'].value)

#-----------------------------------------------------------------------

Cell operation 

a cell operation  

write value to single cell   ws['B1'] = '3.14%'
ws.cell(row=4, column=2, value=10)
append a row to a worksheet  ws.append(row)

for i in range(1,101):
   for j in range(1,101):
      ws.cell(row=i, column=j,value=10)

read vauel from cell  ws['B1'].value

Accessing many cells

Ranges of cells can be accessed using slicing

cell_range = ws['A1':'C2']

Ranges of rows or columns can be obtained similarly:

colC = ws['C']
col_range = ws['C:D']
row10 = ws[10]
row_range = ws[5:10]

Using number formats

wb = Workbook()
ws = wb.active 

# set date using a Python datetime
ws['A1'] = datetime.datetime(2010, 7, 21)
ws['A1'].number_format
'yyyy-mm-dd h:mm:ss'

# You can enable type inference on a case-by-case basis
wb.guess_types = True
# set percentage using a string followed by the percent sign
 ws['B1'] = '3.14%'

wb.guess_types = False
ws['B1'].value  #0.031400000000000004
ws['B1'].number_format

cell use formulae

# add a simple formula
ws["A1"] = "=SUM(1, 1)"
wb.save("formula.xlsx")

Merge / Unmerge cells

Inserting an image

 

Worksheet Tables Operations 

Worksheet tables are references to groups of cells. This makes certain operations such as styling the cells in a table easier.

Creating a table

from openpyxl import Workbook
from openpyxl.worksheet.table import Table, TableStyleInfo

wb = Workbook()
ws = wb.active

data = [
    ['Apples', 10000, 5000, 8000, 6000],
    ['Pears',   2000, 3000, 4000, 5000],
    ['Bananas', 6000, 6000, 6500, 6000],
    ['Oranges',  500,  300,  200,  700],
]

# add column headings. NB. these must be strings
ws.append(["Fruit", "2011", "2012", "2013", "2014"])
for row in data:
    ws.append(row)

tab = Table(displayName="Table1", ref="A1:E5")

# Add a default style with striped rows and banded columns
style = TableStyleInfo(name="TableStyleMedium9", showFirstColumn=False,
                       showLastColumn=False, showRowStripes=True, showColumnStripes=True)
tab.tableStyleInfo = style
ws.add_table(tab)
wb.save("table.xlsx")

Working with styles

Styles are used to change the look of your data while displayed on screen. They are also used to determine the formatting for numbers.

  • font to set font size, color, underlining, etc.
  • fill to set a pattern or color gradient
  • border to set borders on a cell
  • cell alignment
  • protection
以下是預設值
from openpyxl.styles import PatternFill, Border, Side, Alignment, Protection, Font
font = Font(name='Calibri',
              size=11,
              bold=False,
              italic=False,
              vertAlign=None,
              underline='none',
              strike=False,
              color='FF000000')
fill = PatternFill(fill_type=None,start_color='FFFFFFFF',end_color='FF000000')
border = Border(left=Side(border_style=None,color='FF000000'),
                  right=Side(border_style=None,color='FF000000'),
                    top=Side(border_style=None,color='FF000000'),
                 bottom=Side(border_style=None,color='FF000000'),
               diagonal=Side(border_style=None,color='FF000000'),
                    diagonal_direction=0,
                    outline=Side(border_style=None,color='FF000000'),
                   vertical=Side(border_style=None,
                               color='FF000000'),
                 horizontal=Side(border_style=None,
                                color='FF000000')
                )
alignment=Alignment(horizontal='general',vrtical='bottom',text_rotation=0,
                    wrap_text=False,shrink_to_fit=False,indent=0)
number_format = 'General'
protection = Protection(locked=True,hidden=False)
改變值的方法為

Cell Styles

 
a1 = ws['A1']
d4 = ws['D4']
ft = Font(color=colors.RED)
a1.font = ft
d4.font = ft

Copying styles

ft1 = Font(name='Arial', size=14)
ft2 = copy(ft1)

Basic Font Colors

font = Font(color=RED)
font = Font(color="FFBB00")

Applying Styles

c = ws['A1']
c.font = Font(size=12)

 

Styling Merged Cells

def style_range(ws, cell_range, border=Border(), fill=None, font=None, alignment=None):
    """
    Apply styles to a range of cells as if they were a single cell.

    :param ws:  Excel worksheet instance
    :param range: An excel range to style (e.g. A1:F20)
    :param border: An openpyxl Border
    :param fill: An openpyxl PatternFill or GradientFill
    :param font: An openpyxl Font object
    """

    top = Border(top=border.top)
    left = Border(left=border.left)
    right = Border(right=border.right)
    bottom = Border(bottom=border.bottom)

    first_cell = ws[cell_range.split(":")[0]]
    if alignment:
        ws.merge_cells(cell_range)
        first_cell.alignment = alignment

    rows = ws[cell_range]
    if font:
        first_cell.font = font

    for cell in rows[0]:
        cell.border = cell.border + top
    for cell in rows[-1]:
        cell.border = cell.border + bottom

    for row in rows:
        l = row[0]
        r = row[-1]
        l.border = l.border + left
        r.border = r.border + right
        if fill:
            for c in row:
                c.fill = fill
wb = Workbook()
ws = wb.active
my_cell = ws['B2']
my_cell.value = "My Cell"
thin = Side(border_style="thin", color="000000")
double = Side(border_style="double", color="ff0000")
border = Border(top=double, left=thin, right=thin, bottom=double)
fill = PatternFill("solid", fgColor="DDDDDD")
fill = GradientFill(stop=("000000", "FFFFFF"))
font = Font(b=True, color="FF0000")
al = Alignment(horizontal="center", vertical="center")
style_range(ws, 'B2:F4', border=border, fill=fill, font=font, alignment=al)
wb.save("styled.xlsx")

Edit Page Setup

ws.page_setup.orientation = ws.ORIENTATION_LANDSCAPE
ws.page_setup.paperSize = ws.PAPERSIZE_TABLOID
ws.page_setup.fitToHeight = 0
ws.page_setup.fitToWidth = 1

Named Styles

Using builtin styles

Chart Operations 

Chart types

The following charts are available:

Creating a chart

Charts are composed of at least one series of one or more data points. Series themselves are comprised of references to cell ranges.

from openpyxl import Workbook
wb = Workbook()
ws = wb.active
for i in range(10):
    ws.append([i])

from openpyxl.chart import BarChart, Reference, Series
values = Reference(ws, min_col=1, min_row=1, max_col=1, max_row=10)
chart = BarChart()
chart.add_data(values)
ws.add_chart(chart, "E15")
wb.save("c:\\tmp\\SampleChart.xlsx")

Styling charts

Advanced charts

Charts can be combined to create new charts:

Using chartsheets

Charts can be added to special worksheets called chartsheets:

文章標籤

stanley 發表在 痞客邦 留言(0) 人氣()

PYTHON HOME 2017Python tutorial  (basic data type & python networking programming)

https://www.tutorialspoint.com/python/python_basic_syntax.htm(Basic)

 

 

 

回主目錄

stanley 發表在 痞客邦 留言(0) 人氣()

記錄如何將 Python 檔案編譯成 exe (執行檔)

  1. 請下載且安裝好 Portable Python 2.7.6.1 (請參考上篇文章)
    Portable Python 2.7.6.1 包含了Py2Exe 0.6.9 模組

  2. 用記事本 編輯.setup.py 和.hello.py 二個檔案

  3. 複製二個檔案到C:\Portable Python 2.7.6.1\App

  4. 開啓一個命令列視窗並且 cd 到 C:\Portable Python 2.7.6.1\App> 

  5. 在cmd裡再輸入 python setup.py install 

  6. python setup.py py2exe

  7. 完成後會在 此路徑下裡 產生出 dist 跟 build 二個資料夾,執行檔與所須的檔案全在 dist 裡

  8. 把 dist copy 至別處測試結果

  9. 在 disk 資料夾內即有一個hello.exe 檔案

  10. 你成功了。

hello.py 

   print ("Hello Python 2.7.6.1")
   input("please key amy key continue...")

  setup.py 檔案內容

from distutils.core import setup
import py2exe
 
setup(
    version = "1.0",
    description = "Print Hello using py2exe",
    name = "Hello",
    console=['hello.py'])

hello.py 是指你寫好的 py 檔。
 

注意事項:

  • Python2.7、Py2Exe、PyQt4 都要下載對版本,目前測試結果只支援 x86 就是 32bit 的版本。
  • Py2Exe 目前只支援 Python 2.x 的版本,並不支援 Python 3.x 版本。

參考文件:

#---------------------------------------------------------------------

另一個要記錄的是當一個dbhello.py 加入了pyodbc.py 時, 且執行產生exe檔時會出現

E:\Portable Python 2.7.6.1\App\dist>hello.exe
Traceback (most recent call last):
  File "hello.py", line 1, in <module>
  File "pyodbc.pyc", line 12, in <module>
  File "pyodbc.pyc", line 10, in __load
RuntimeError: Unable to import decimal
#-------------------------
這個錯誤表示缺少了 decimal module

所以要改寫如下

dbsetup.py 

from distutils.core import setup
import py2exe
 
setup(
    console=['dbhello.py'], 
    options = {"py2exe": {"includes" : "decimal"}}  
)

 

 

 

 

 

 

 

 

文章標籤

stanley 發表在 痞客邦 留言(0) 人氣()

Portable Python 2.7.6.1

This package contains following applications/libraries:

  • PyScripter v2.5.3
  • PyCharm Community Edition 3.1.2 (Thanks to cebik)
  • NumPy 1.8.1
  • SciPy 0.13.3
  • Matplotlib 1.3.1
  • PyWin32 218
  • Django 1.6.2
  • PIL 1.1.7
  • Py2Exe 0.6.9
  • wxPython 3.0.0.0
  • NetworkX 1.7
  • Lxml 3.3.4
  • PySerial 2.7
  • PyODBC 3.0.7
  • PyGame 1.9.1
  • PyGTK 2.24.2
  • PyQt 4.10.4
  • IPython 1.2.1
  • Pandas 0.11.0
  • Dateutil 2.2
  • PyParsing 2.0.1
  • Six 1.6.1
  • XLRD 0.9.2
  • XLWT 0.7.5
  • XLUtils 1.7.0
  • OpenPyXL 1.8.5

Package file size (compressed): 237MB

Installed size: based on selected packages, between 50MB and 850MB

Warning: default installation installs all packages and this can be a long process especially if the target location is USB drive. Packages can be selected/deselected during the installation process.

Package file hash:

  • MD5 - 5b480c1bbbc06b779a7d150c26f2147d
  • SHA1 - 10bfb41048cb2017af507be059c842403e00fd8d

Download this package by using one of the mirrors:

Country Mirror Type
Belgium Belnet.be HTTP FTP
Ireland HEAnet.ie HTTP FTP
Netherlands NLUUG.nl HTTP FTP
USA OSUOSL.org HTTP FTP
USA Rowan.edu HTTP

參考資料: http://portablepython.com/wiki/PortablePython2.7.6.1/

檢查模組版本
import numpy
print numpy.__version__
1.8.0
文章標籤

stanley 發表在 痞客邦 留言(0) 人氣()

  • 我們首先要找到己經編輯好的package,可從下面網站 here找到你要安裝的Package, 
  • 下載且放在某個資料夾(例如C:\tmp)
  • 將 *.wml 檔改成.*.exe
  • 打開一個cmd 並切換至Scripts 資料夾 (通常在 Apps資料夾下面)
  • 鍵入easy_install C:\tmp\XXXX.2.7.exe 

測試是否有安裝成功模組,例如

>>> import numpy
>>> print numpy.__version__
1.8.0

另一種方法是在另一台機器安裝好新版的portable python且更新完你將會使用到的模組,然後將整個portable python的目錄壓縮後,搬移到另一台機器上,如此你將可免除重複安裝的工作。
或者你安裝完新的portable python模組後再把新的模組資料夾更新到舊的portable python,如此也是可以工作的。像小編的工作環境是無法連上網路,所以無法更新模組,所以小編在家安裝完模組後,再看檔案日期,壓縮完新的模組再複製到公司的電腦上,如此也是可以工作的。

 

 

 

文章標籤

stanley 發表在 痞客邦 留言(0) 人氣()

Quick reference for the ESP8266

Micropython on ESP8266 Workshop Documentation (2017,3,28)

boot.py

>>> import os
>>> os.listdir()
['boot.py', 'port_config.py']

# This file is executed on every boot (including wake-boot from deepsleep) import gc import webrepl webrepl.start() gc.collect()

FIile Content

>>> f = open('boot.py')
>>> f.read()
'# This file is executed on every boot (including wake-boot from deepsleep)\nimport gc\n#import webrepl\n#webrepl.start()\ngc.collect()\n'

Micropython ESP8266 Boot.py & Main.py Example

boot.py

# This file is executed on every boot (including wake-boot from deepsleep)
import network
import gc
import webrepl
 
ap_if = network.WLAN(network.AP_IF)
sta_if = network.WLAN(network.STA_IF)
 
ap_if.active(False)
 
sta_if.active(True)
sta_if.connect('filewalker','mypasswd')
 
#import esp
#esp.osdebug(None) 
webrepl.start() 
gc.collect()
---------------------------------------------------------------
main.py
micropython-esp8266-scheduler.py
esp8266_relays.py
---------------------------------------------------------------

Boot process

Once the filesystem is mounted, boot.py is executed from it. The standard version of this file is created during first-time module set up and has commands to start a WebREPL daemon (disabled by default, configurable with webrepl_setup module), etc. This file is customizable by end users (for example, you may want to set some parameters or add other services which should be run on a module start-up). But keep in mind that incorrect modifications to boot.py may still lead to boot loops or lock ups, requiring to reflash a module from scratch. (In particular, it’s recommended that you use either webrepl_setup module or manual editing to configure WebREPL, but not both).

As a final step of boot procedure, main.py is executed from filesystem, if exists. This file is a hook to start up a user application each time on boot (instead of going to REPL). For small test applications, you may name them directly as main.py, and upload to module, but instead it’s recommended to keep your application(s) in separate files, and have just the following in main.py:

import my_app
my_app.main()
This will allow to keep the structure of your application clear, as well as allow to install multiple applications on a board, and switch among them.
#---------------------------
很好用的指令,查看ESP8266的設定值
 
import port_diag
 

MicroPython v1.9.1-8-g7213e78d on 2017-06-12; ESP module with ESP8266
Type "help()" for more information.
>>>
import port_diag
FlashROM:
Flash ID: 1640ef (Vendor: ef Device: 4016)
Flash bootloader data:
Byte @2: 02
Byte @3: 40 (Flash size: 4MB Flash freq: 40MHZ)
Firmware checksum:
size: 598416
md5: dae90ece36362127bce73f27cefe47fd
True

Networking:

STA ifconfig: ('192.168.1.105', '255.255.255.0', '192.168.1.1', '61.64.127.1')
AP ifconfig: ('192.168.4.1', '255.255.255.0', '192.168.4.1', '61.64.127.1')
Free WiFi driver buffers of type:
0: 8 (1,2 TX)
1: 0 (4 Mngmt TX(len: 0x41-0x100))
2: 8 (5 Mngmt TX (len: 0-0x40))
3: 4 (7)
4: 7 (8 RX)
lwIP PCBs:
Active PCB states:
Listen PCB states:
TIME-WAIT PCB states:
#---------------------------

Wifi ap mode default password
 

After a fresh install and boot the device configures itself as a WiFi access point (AP) that you can connect to. The ESSID is of the form MicroPython-xxxxxx
where the x’s are replaced with part of the MAC address of your device (so will be the same everytime, and most likely different for all ESP8266 chips).
The password for the WiFi is micropythoN (note the upper-case N). Its IP address will be 192.168.4.1 once you connect to its network.
WiFi configuration will be discussed in more detail later in the tutorial.

#--------------------------------
Controlling relays using Micropython and an ESP8266

MicroPython http_server_simplistic.py example

http cleint & server



http://www.instructables.com/id/ESP8266-Light-Sensor/

#--------------------------------------------

Micropython PWM control

  1.   import time
  2. import machine
  3. pwm = machine.PWM(machine.Pin(15))
  4. pwm.freq(60)
  5. while True:
  6.     for i in range(1024):
  7.         pwm.duty(i)
  8.         time.sleep(0.001)
  9.     for i in range(1023, -1, -1):
  10.         pwm.duty(i)
  11.         time.sleep(0.001)  

Micropython GPIO control

  1. from machine import Pin    #匯入 Pin 類別
  2. pin=Pin(2, Pin.OUT)          #定義 GPIO 2 為輸出腳
  3. import time                         #匯入時間模組
  4. while True:                         #無窮迴圈
  5.     pin.high()                        #點亮 LED
  6.     time.sleep(1.0)                #暫停 1 秒
  7.     pin.low()                         #熄滅 LED
  8.     time.sleep(1.0)                #暫停 1 秒

Micropython GPIO as Input control with switch bound problem

  1. import time   
  2. from machine import Pin
  3. swPin=Pin(0, Pin.IN, Pin.PULL_UP)
  4. ledPin=Pin(2, Pin.OUT)
  5. while True:
  6.     if not swPin.value():      #若按鈕被按下 (接地)
  7.         ledPin.value(not ledPin.value())     #反轉 LED 狀態
  8.         time.sleep_ms(300)                        #暫停 0.3 秒
  9.         while not swPin.value():                 #按鈕若還在按下狀態就在迴圈繞, 否則跳出去
  10.             pass
     

MicroPython: External interrupts

  1. import machine
  2. interruptCounter = 0
  3. totalInterruptsCounter = 0
  4. def callback(pin):
  5.   global interruptCounter
  6.   interruptCounter = interruptCounter+1
  7. p25 = machine.Pin(25, machine.Pin.IN, machine.Pin.PULL_UP)
  8. p25.irq(trigger=machine.Pin.IRQ_FALLING, handler=callback)
  9. while True:
  10.   if interruptCounter>0:
  11.     state = machine.disable_irq()
  12.     interruptCounter = interruptCounter-1
  13.     machine.enable_irq(state)
  14.     totalInterruptsCounter = totalInterruptsCounter+1
  15.     print("Interrupt has occurred: " + str(totalInterruptsCounter))

MicroPython: Timer interrupts

  1. import machine
  2. interruptCounter = 0
  3. totalInterruptsCounter = 0
  4. timer = machine.Timer(0
  5. def handleInterrupt(timer):
  6.   global interruptCounter
  7.   interruptCounter = interruptCounter+1
  8. timer.init(period=1000, mode=machine.Timer.PERIODIC, callback=handleInterrupt)
  9. while True:
  10.   if interruptCounter>0:
  11.     state = machine.disable_irq()
  12.     interruptCounter = interruptCounter-1
  13.     machine.enable_irq(state)
  14.     totalInterruptsCounter = totalInterruptsCounter+1
  15.     print("Interrupt has occurred: " + str(totalInterruptsCounter))

 MicroPython: Creating a thread(1)

  1. import machine
  2. import _thread
  3. import time
  4. def testThread():
  5. while True:
  6.     print("Hello from thread")
  7.     time.sleep(2)
  8.  
  9. _thread.start_new_thread(testThread, ())

 MicroPython: Creating a thread(2)

  1. import _thread
  2. import time
  3.  
  4. def th_func(delay, id):
  5.     while True:
  6.         time.sleep(delay)
  7.         print('Running thread %d' % id)
  8.  
  9. for i in range(2):
  10.     _thread.start_new_thread(th_func, (i + 1, i))

MicroPython: Passing arguments to a thread function(3)

  1. import _thread
  2. def threadFunction(description, count):
  3.   print(description)
  4.   i = 0
  5.   while i < count:
  6.     print("Iteration: " + str(i) )
  7.     i=i+1
  8.  
  9. _thread.start_new_thread(threadFunction, ("Thread test function", 5))

MicroPython: : thread function with lock(4)

  1. import _thread
  2. import time
  3. lock=_thread.allocate_lock()
  4. def funcA(sec):
  5.   time.sleep(sec)
  6.   with lock:
  7.     print('Running thread A')
  8.   _thread.exit()
  9. def funcB(sec):
  10. time.sleep(sec)
  11.  with lock:
  12.    print('Running thread B')
  13.    print('Thread B sleep 5 seconds')
  14.    time.sleep(5)
  15.    print('thread B weakup')
  16.  _thread.exit()
  17. def funcC():
  18.    print('Running thread C')
  19.  _thread.exit()
  20.  
  21. _thread.start_new_thread(funcA, (2,))
  22. _thread.start_new_thread(funcB, (1,))
  23. _thread.start_new_thread(funcC, ())
  24. while True:
  25.    pass

Expected results
1. A sleeps for 2 seconds
2. B sleeps for 1 second
3. Executes C in priority without any limitation
4. B wakes up and get the lock then sleep for 5 seconds
5. A wakes up and failed to get lock, blocked until B releases the lock
6. B sleeps for 5 seconds and releases the lock
7. Executes A

MicroPython:  thread(5)

  1. import _thread
    import time

    # Define a function for the thread
    def print_time( threadName, delay):
       count = 0
       while count < 5:
          time.sleep(delay)
          count += 1
          print ("%s: %s" % ( threadName, time.time() ))

    # Create two threads as follows
    try:
       _thread.start_new_thread( print_time, ("Thread-1", 2, ) )
       _thread.start_new_thread( print_time, ("Thread-2", 4, ) )
    except:
       print ("Error: unable to start thread")

    while 1:
       pass

    Thread-1: 5582
    Thread-2: 5584
    Thread-1: 5584
    Thread-1: 5586
    Thread-2: 5588
    Thread-1: 5588
    Thread-1: 5590
    Thread-2: 5592
    Thread-2: 5596
    Thread-2: 5600

MicroPython:  thread(6)

  1. import _thread
    import time

    exitFlag = 0
          
    class myThread ():
       def __init__(self, threadID, name, counter):      
          self.threadID = threadID
          self.name = name
          self.counter = counter
       def run(self):
          print ("Starting " + self.name)
          print_time(self.name, self.counter, 5)
          print ("Exiting " + self.name)

    def print_time(threadName, delay, counter):
       while counter:
          if exitFlag:
             threadName.exit()
          time.sleep(delay)
          print ("%s: %s" % (threadName, time.time()))
          counter -= 1

    # Create new threads
    thread1 = myThread(1, "Thread-1", 1)
    thread2 = myThread(2, "Thread-2", 2)

    # Start new Threads
    thread1.run()
    thread2.run()
    print ("Exiting Main Thread")

    Starting Thread-1
    Thread-1: 7023
    Thread-1: 7024
    Thread-1: 7025
    Thread-1: 7026
    Thread-1: 7027
    Exiting Thread-1
    Starting Thread-2
    Thread-2: 7029
    Thread-2: 7031
    Thread-2: 7033
    Thread-2: 7035
    Thread-2: 7037
    Exiting Thread-2
    Exiting Main Thread

MicroPython: : Reading a file

  1. file = open ("initialFile.txt", "w")
  2. file.write("First Line \n")
  3. file.write("Second Line")
  4. file.close()
  5.  
  6. import os
  7. os.listdir()
  8.  
  9. file = open("initialFile.txt", "r")
  10. file.read()
  11. file.close()
  12.  

MicroPython: : Writing  a file

  1. file = open("myTestFile.txt", "w")
  2. print(type(file))
  3. file.write("Writing content from MicroPython")
  4. file.close()
  5.  

MicroPython: Running a script from the file system

  1. def echo(content):
  2.    print (content)
  3.  
  4. print("Running a script from the file system!")
  5. echo("Invoking a function")
  6.  
  7. import os
  8. os.listdir()
  9.  
  10. import script
  11. script.echo("Running the imported function")

MicroPython: String split method 

  1. myString = "one|two|three"
  2. print(myString.split("|",0))
  3. print(myString.split("|",1))
  4. print(myString.split("|",2))
  5. print(myString.split("|",3))

 

 

 

 

 

 

  1.  
文章標籤

stanley 發表在 痞客邦 留言(0) 人氣()

2017..04.11 星期二
 

Python standard libraries and micro-libraries

Libraries specific to the ESP8266

The following libraries are specific to the ESP8266.

General board control

The MicroPython REPL is on UART0 (GPIO1=TX, GPIO3=RX) at baudrate 115200. Tab-completion is useful to find out what methods an object has. Paste mode (ctrl-E) is useful to paste a large slab of Python code into the REPL.

The machine module:

import machine
machine.freq() # get the current frequency of the CPU
machine.freq(160000000) # set the CPU frequency to 160 MHz

The esp module:

import esp
esp.osdebug(None) # turn off vendor O/S debugging messages
esp.osdebug(0) # redirect vendor O/S debugging messages to UART(0)

Networking

The network module:

import network
wlan = network.WLAN(network.STA_IF) # create station interface
wlan.active(True) # activate the interface
wlan.scan() # scan for access points
wlan.isconnected() # check if the station is connected to an AP
wlan.connect('essid', 'password') # connect to an AP
wlan.config('mac') # get the interface's MAC adddress
wlan.ifconfig() # get the interface's IP/netmask/gw/DNS addresses

ap = network.WLAN(network.AP_IF) # create access-point interface
ap.active(True) # activate the interface
ap.config(essid='ESP-AP') # set the ESSID of the access point

A useful function for connecting to your local WiFi network is:

def do_connect():
     import network
     wlan = network.WLAN(network.STA_IF)
     wlan.active(True)
     if not wlan.isconnected():
         print('connecting to network...')
         wlan.connect('essid', 'password')
         while not wlan.isconnected():
            pass
     print('network config:', wlan.ifconfig())

Once the network is established the socket module can be used to create and use TCP/UDP sockets as usual.

Delay and timing

Use the time module:

import time
time.sleep(1) # sleep for 1 second
time.sleep_ms(500) # sleep for 500 milliseconds
time.sleep_us(10) # sleep for 10 microseconds
start = time.ticks_ms() # get millisecond counter
delta = time.ticks_diff(time.ticks_ms(), start) # compute time difference

Timers

Virtual (RTOS-based) timers are supported. Use the machine.Timer class with timer ID of -1:

from machine import Timer
tim = Timer(-1)
tim.init(period=5000, mode=Timer.ONE_SHOT, callback=lambda t:print(1))
tim.init(period=2000, mode=Timer.PERIODIC, callback=lambda t:print(2))

The period is in milliseconds.

Pins and GPIO

Use the machine.Pin class:

from machine import Pin
p0 = Pin(0, Pin.OUT) # create output pin on GPIO0
p0.high() # set pin to high p0.low() # set pin to low
p0.value(1) # set pin to high
p2 = Pin(2, Pin.IN) # create input pin on GPIO2
print(p2.value()) # get value, 0 or 1
p4 = Pin(4, Pin.IN, Pin.PULL_UP) # enable internal pull-up resistor
p5 = Pin(5, Pin.OUT, value=1) # set pin high on creation

Available pins are: 0, 1, 2, 3, 4, 5, 12, 13, 14, 15, 16, which correspond to the actual GPIO pin numbers of ESP8266 chip. Note that many end-user boards use their own adhoc pin numbering (marked e.g. D0, D1, ...). As MicroPython supports different boards and modules, physical pin numbering was chosen as the lowest common denominator. For mapping between board logical pins and physical chip pins, consult your board documentation.

Note that Pin(1) and Pin(3) are REPL UART TX and RX respectively. Also note that Pin(16) is a special pin (used for wakeup from deepsleep mode) and may be not available for use with higher-level classes like Neopixel.

PWM (pulse width modulation)

PWM can be enabled on all pins except Pin(16). There is a single frequency for all channels, with range between 1 and 1000 (measured in Hz). The duty cycle is between 0 and 1023 inclusive.

Use the machine.PWM class:

from machine import Pin, PWM
pwm0 = PWM(Pin(0)) # create PWM object from a pin
pwm0.freq() # get current frequency
pwm0.freq(1000) # set frequency
pwm0.duty() # get current duty cycle
pwm0.duty(200) # set duty cycle
pwm0.deinit() # turn off PWM on the pin
pwm2 = PWM(Pin(2), freq=500, duty=512) # create and configure in one go

ADC (analog to digital conversion)

ADC is available on a dedicated pin. Note that input voltages on the ADC pin must be between 0v and 1.0v.

Use the machine.ADC class:

from machine import ADC
adc = ADC(0) # create ADC object on ADC pin
adc.read() # read value, 0-1024

 

Software SPI bus

There are two SPI drivers. One is implemented in software (bit-banging) and works on all pins:

from machine import Pin, SPI

# construct an SPI bus on the given pins
# polarity is the idle state of SCK
# phase=0 means sample on the first edge of SCK, phase=1 means the second
spi = SPI(-1, baudrate=100000, polarity=1, phase=0, sck=Pin(0), mosi=Pin(2), miso=Pin(4))

spi.init(baudrate=200000) # set the baudrate

spi.read(10)            # read 10 bytes on MISO
spi.read(10, 0xff)      # read 10 bytes while outputing 0xff on MOSI

buf = bytearray(50)     # create a buffer
spi.readinto(buf)       # read into the given buffer (reads 50 bytes in this case)
spi.readinto(buf, 0xff) # read into the given buffer and output 0xff on MOSI

spi.write(b'12345')     # write 5 bytes on MOSI

buf = bytearray(4)      # create a buffer
spi.write_readinto(b'1234', buf) # write to MOSI and read from MISO into the buffer
spi.write_readinto(buf, buf) # write buf to MOSI and read MISO back into buf

Hardware SPI bus

The hardware SPI is faster (up to 80Mhz), but only works on following pins: MISO is GPIO12, MOSI is GPIO13, and SCK is GPIO14. It has the same methods as the bitbanging SPI class above, except for the pin parameters for the constructor and init (as those are fixed):

from machine import Pin, SPI

hspi = SPI(1, baudrate=80000000, polarity=0, phase=0)

(SPI(0) is used for FlashROM and not available to users.)

I2C bus

The I2C driver is implemented in software and works on all pins:

from machine import Pin, I2C

# construct an I2C bus
i2c = I2C(scl=Pin(5), sda=Pin(4), freq=100000)

i2c.readfrom(0x3a, 4)   # read 4 bytes from slave device with address 0x3a
i2c.writeto(0x3a, '12') # write '12' to slave device with address 0x3a

buf = bytearray(10)     # create a buffer with 10 bytes
i2c.writeto(0x3a, buf)  # write the given buffer to the slave

Deep-sleep mode

Connect GPIO16 to the reset pin (RST on HUZZAH). Then the following code can be used to sleep, wake and check the reset cause:

import machine

# configure RTC.ALARM0 to be able to wake the device
rtc = machine.RTC()
rtc.irq(trigger=rtc.ALARM0, wake=machine.DEEPSLEEP)

# check if the device woke from a deep sleep
if machine.reset_cause() == machine.DEEPSLEEP_RESET:
    print('woke from a deep sleep')

# set RTC.ALARM0 to fire after 10 seconds (waking the device)
rtc.alarm(rtc.ALARM0, 10000)

# put the device to sleep
machine.deepsleep()

OneWire driver

The OneWire driver is implemented in software and works on all pins:

from machine import Pin
import onewire

ow = onewire.OneWire(Pin(12)) # create a OneWire bus on GPIO12
ow.scan()               # return a list of devices on the bus
ow.reset()              # reset the bus
ow.readbyte()           # read a byte
ow.writebyte(0x12)      # write a byte on the bus
ow.write('123')         # write bytes on the bus
ow.select_rom(b'12345678') # select a specific device by its ROM code

There is a specific driver for DS18S20 and DS18B20 devices:

import time, ds18x20
ds = ds18x20.DS18X20(ow)
roms = ds.scan()
ds.convert_temp()
time.sleep_ms(750)
for rom in roms:
    print(ds.read_temp(rom))

Be sure to put a 4.7k pull-up resistor on the data line. Note that the convert_temp() method must be called each time you want to sample the temperature.

NeoPixel driver

Use the neopixel module:

from machine import Pin
from neopixel import NeoPixel

pin = Pin(0, Pin.OUT)   # set GPIO0 to output to drive NeoPixels
np = NeoPixel(pin, 8)   # create NeoPixel driver on GPIO0 for 8 pixels
np[0] = (255, 255, 255) # set the first pixel to white
np.write()              # write data to all pixels
r, g, b = np[0]         # get first pixel colour

For low-level driving of a NeoPixel:

import esp
esp.neopixel_write(pin, grb_buf, is800khz)

APA102 driver

Use the apa102 module:

from machine import Pin
from apa102 import APA102

clock = Pin(14, Pin.OUT)     # set GPIO14 to output to drive the clock
data = Pin(13, Pin.OUT)      # set GPIO13 to output to drive the data
apa = APA102(clock, data, 8) # create APA102 driver on the clock and the data pin for 8 pixels
apa[0] = (255, 255, 255, 31) # set the first pixel to white with a maximum brightness of 31
apa.write()                  # write data to all pixels
r, g, b, brightness = apa[0] # get first pixel colour

For low-level driving of an APA102:

import esp
esp.apa102_write(clock_pin, data_pin, rgbi_buf)

DHT driver

The DHT driver is implemented in software and works on all pins:

import dht
import machine

d = dht.DHT11(machine.Pin(4))
d.measure()
d.temperature() # eg. 23 (°C)
d.humidity()    # eg. 41 (% RH)

d = dht.DHT22(machine.Pin(4))
d.measure()
d.temperature() # eg. 23.6 (°C)
d.humidity()    # eg. 41.3 (% RH)

WebREPL (web browser interactive prompt)

WebREPL (REPL over WebSockets, accessible via a web browser) is an experimental feature available in ESP8266 port. Download web client from https://github.com/micropython/webrepl(hosted version available  at http://micropython.org/webrepl), and configure it by executing:

import webrepl_setup

and following on-screen instructions. After reboot, it will be available for connection. If you disabled automatic start-up on boot, you may run configured daemon on demand using:

import webrepl
webrepl.start()

The supported way to use WebREPL is by connecting to ESP8266 access point, but the daemon is also started on STA interface if it is active, so if your router is set up and works correctly, you may also use WebREPL while connected to your normal Internet access point (use the ESP8266 AP connection method if you face any issues).

Besides terminal/command prompt access, WebREPL also has provision for file transfer (both upload and download). Web client has buttons for the corresponding functions, or you can use command-line client webrepl_cli.py from the repository above.

See the MicroPython forum for other community-supported alternatives to transfer files to ESP8266.

 

文章標籤

stanley 發表在 痞客邦 留言(0) 人氣()

在 Python 中設定GPIO.BOARD與GPIO.BCM有何不同
import RPi.GPIO as GPIO

GPIO.setmode(GPIO.BOARD)

或者

GPIO.setmode(GPIO.BCM)

這個GPIO.BOARD 選項是指定在電路版上接脚的號碼
這個GPIO.BCM 選項是指定GPIO後面的號碼
在撰寫程式時要先清楚你指定的數字要使用的是GPIO.BOARD或是GPIO.BCM的方式

 

文章標籤

stanley 發表在 痞客邦 留言(0) 人氣()

Python 是一種物件導向直譯式電腦程式語言。它的語法簡單,支援命令式程式設計物件導向程式設計函數式編程面向側面的程式設計泛型編程多種編程範式。它包含了一組功能完備的標準庫,能夠輕鬆完成很多常見的任務。Python具備垃圾回收功能,能夠自動管理記憶體使用。它經常被當作腳本語言用於處理系統管理任務和網路程式編寫,然而它也非常適合完成各種高階任務。Python虛擬機本身幾乎可以在所有的作業系統中運行。
使用一些諸如py2exePyPyPyInstaller之類的工具可以將Python原始碼轉換成可以脫離Python解釋器執行的程式。
它與他程式語言最大的不同大於使用縮排來定義語句塊。如此使得程式較為簡潔,簡單。
在Linux 環境中
Python
#!/usr/bin/python
print "Hello World!"

 第二個較複雜的程式架構

import os

class Foo(object):
   def __init__(self):
       self.val = None
   def __str__(self):
       return "foo - val: {0}".format(self.val)

def f():
   l = []
   for i in range(3):
       foo = Foo()
       #print "id of foo: {0}".format(id(foo))
       #print "foo is: {0}".format(foo)
       l.append(foo)
   return l

def main():
   d = {}
   l = f()
   d['k'] = l
   print "list l has {0} objects of type Foo()".format(len(l)) 

if __name__ == "__main__":
   main()

 

 

文章標籤

stanley 發表在 痞客邦 留言(0) 人氣()

«123
Close

您尚未登入,將以訪客身份留言。亦可以上方服務帳號登入留言

請輸入暱稱 ( 最多顯示 6 個中文字元 )

請輸入標題 ( 最多顯示 9 個中文字元 )

請輸入內容 ( 最多 140 個中文字元 )

reload

請輸入左方認證碼:

看不懂,換張圖

請輸入驗證碼