2014年10月31日 星期五

Raspberry Pi module b+ GPIO Mode





最近定了這個新的版子,用舊的方法方法寫了以後發現PIN28以後的GPIO竟然出現錯誤訊息
valueError the channel send is invalid


看了一下發現很多人也有這樣問題
解答是在PI裡面要用另外一種模式BCM mode,就可以控制新增的GPIO
GPIO.setmode(GPIO.BCM)


The GPIO.BOARD option specifies that you are referring to the pins by the number of the pin the the plug - i.e the numbers printed on the board (e.g. P1) and in the middle of the diagrams below.
The GPIO.BCM option means that you are referring to the pins by the "Broadcom SOC channel" number, these are the numbers after "GPIO" in the green rectangles around the outside of the below diagrams:
Unfortunately the BCM numbers changed between versions of the Model B, and you'll need to work out which one you have guide here. So it may be safer to use the BOARD numbers if you are going to use more than one pi in a project.


Board mode寫的腳位就是pin 的腳位

BCM mode 寫的是在PINGPIO的編號,要查一下自己Pi的硬體版本

ps. SDA與SCL雖然寫是GPIO,但是不能被讀出,不要拿這兩個來當普通GPIO


2014年10月28日 星期二

Python Function,Module,Class,Package Note

Python Function,Module,Class,Package Note

Reference
https://docs.python.org/3/tutorial/modules.html
http://openhome.cc/Gossip/Python/Class.html

Function
function 可以用兩種方式來表示def, lambda
def max(a, b):
   return a if a > b else b

lambda a, b: a if a < b else b

這樣的函式稱為 λ 函式或是匿名函式(Anonymous function,當然,你可以將函式指定給變數:
min = lambda a, b: a if a < b else b
minimum = min
min(10, 20) # 傳回10

Module
Python 中,模組是幾個重要抽象層的機制之一,也許是最自然的機制之一,只要你建立了一個原始碼檔案 modu.py,你就建立了一個模組 modu,原始碼主檔名就是模組名稱。
import modu 陳述句會在相同目錄下尋找 modu.py,如果沒找到,則會試著尋找在 sys.path中遞迴地尋找 modu.py,如果還是沒有,則會引發 ImportError 例外。
模組提供了名稱空間。模組中的變數、函式與類別,基本上需透過模組的名稱空間來取得。在 Python 中,importimport as 與 from import 是陳述句
from modu import max, min   # import這兩個函式
from modu import *          # import全部函式
或是可以使用modulename.functionname來呼叫在別的module中的function ,ex: modu.max


Note 可以利用imp.reload()來自動載入更新過的檔案
For efficiency reasons, each module is only imported once per interpreter session. Therefore, if you change your modules, you must restart the interpreter – or, if it’s just one module you want to test interactively, use imp.reload(), e.g.import imp; imp.reload(modulename).


_name__
每一個module裡面都會有個__name__的全域變數,指向module的名稱
Within a module, the module’s name (as a string) is available as the value of the global variable __name__.
if __name__ == "__main__"
在咬一口python中對這有很好的例子 http://ibiblio.org/g2swap/byteofpython/read/module-name.html
這表示如果直接執行python檔案,__name__會指向__main__,但是如果是從別的file import這個python檔案,__name__會指向module的名稱
When the Python interpreter reads a source file, it executes all of the code found in it. Before executing the code, it will define a few special variables. For example, if the python interpreter is running that module (the source file) as the main program, it sets the special __name__ variable to have a value "__main__". If this file is being imported from another module, __name__ will be set to the module's name.

using_name.py
#!/usr/bin/python
# Filename: using_name.py

if __name__ == '__main__':
        print 'This program is being run by itself'
else:
        print 'I am being imported from another module'

>>> ========================= RESTART ================================
>>>
This program is being run by itself
>>> import using_name
I am being imported from another module
>>> using_name.__name__
'using_name'
>>>


Class
Gossip@openhome裡面寫的一個範例
class Account:
    def __init__(self, number, name):
        self.number = number
        self.name = name
        self.balance = 0
        
    def deposit(self, amount):
        if amount <= 0:
            raise ValueError('must be positive')
        self.balance += amount
        
    def withdraw(self, amount):
        if amount <= self.balance:
            self.balance -= amount
        else:
            raise RuntimeError('balance not enough')

每個函數def都需要一個self做為指標,就像c++裡面的this一樣,numbername是這個class對外的變數,blance則是內部的變數

>>> acct = Account('123456', 'mary')
>>> acct.number
'123456'
>>> acct.name
'mary'
>>> acct.deposit(100)
>>> acct.balance
100
>>> acct.withdraw(50)
>>> acct.balance
50



Package

假設現在你有一些 .py 檔案,別人同樣也有一堆 .py 檔案,你們的檔案現在得放在同一專案中,那麼檔案名稱衝突是有可能發生的,最好是為你們的 .py 檔案分別開設目錄。使用 Python 時,你可以在開設的目錄中放個 __init__.py 檔案,這樣 Python 就會將這個目錄視為一個套件,而目錄名稱就是套件名稱。
使用 import pack.modu 陳述時,Python 會尋找 pack 目錄,看看裏頭是否有 __init__.py 檔案,然後看看目錄中是否有個 modu.py 檔案。__init__.py 檔案空白也無所謂,實際上當中也可以寫些程式碼,用來執行這個套件中都會需要的初始工作,不過慣例上,除非你有真正不得已的理由,請保持 __init__.py 檔案空白。在找到模組後,實際上會執行其中頂層範疇中的程式碼,之後,模組中的變數、函式、類別等名稱,可以透過 pack.modu 來取得。
引入參數的階層是 package.module
如果階層較長(多層次的套件),可以用import as
sound/                          Top-level package
      __init__.py               Initialize the sound package
      formats/                  Subpackage for file format conversions
              __init__.py
              wavread.py
              wavwrite.py
              aiffread.py
              aiffwrite.py
              auread.py
              auwrite.py
              ...
      effects/                  Subpackage for sound effects
              __init__.py
              echo.py
              surround.py
              reverse.py
              ...
      filters/                  Subpackage for filters
              __init__.py
              equalizer.py
              vocoder.py
              karaoke.py
              ...



import sound.effects.echo
sound.effects.echo.echofilter(input, output, delay=0.7, atten=4)

from sound.effects import echo
echo.echofilter(input, output, delay=0.7, atten=4)

from sound.effects.echo import echofilter
echofilter(input, output, delay=0.7, atten=4)


python data structure note

Python筆記整理(Python 3.4)
Reference

Python tutorial

http://www.codedata.com.tw/python/python-tutorial-the-2nd-class-2-container-flow-for-comprehension/


運算子
>>> 17 / 3 # classic division returns a float ,單斜線浮點數
5.666666666666667

>>> 17 // 3 # floor division discards the fractional part,雙斜線浮點數整數
5

>>> 17 % 3 # the % operator returns the remainder of the division, 百分比餘數
2

>>> 5 ** 2 # 5 squared,雙星號平方
25

>>> tax = 12.5 / 100
>>> price = 100.50
>>> price * tax
12.5625
>>> price + _ # 變數_,可以用來表示最後的運算結果
113.0625

>>> a = 5
>>> a += 1 # 連加不使用++, 而是+=
>>> a
6


字串string
字串可以用單引號或是雙引號來表示,反斜線用來保護要印出的引號
>>> 'spam eggs' # single quotes
'spam eggs'
>>> "doesn't" # ...or use double quotes instead
"doesn't"
>>> "\"Yes,\" he said."
'"Yes," he said.'

r來避免固定字
>>> print('C:\some\name') # here \n means newline!
C:\some
ame
>>> print(r'C:\some\name') # note the r before the quote
C:\some\name

印出多行可使用"""...""" or '''…'''
print("""\
Usage: thingy [OPTIONS]
-h Display this usage message
-H hostname Hostname to connect to
""")

字串可以用加號來連接,用星號來複製
>>> 3 * 'un' + 'ium'
'unununium'

字串陣列引數可以有正負號
+---+---+---+---+---+---+
| P | y | t | h | o | n |
+---+---+---+---+---+---+
0 1 2 3 4 5 6
-6 -5 -4 -3 -2 -1
>>> word[:2] # character from the beginning to position 2 (excluded)
'Py'
>>> word[-2:] # characters from the second-last (included) to the end
'on'

陣列裡的數值無法被改變(immutable)
>>> word[0] = 'J'
...
TypeError: 'str' object does not support item assignment

可以用len()來偵測字串長度
>>> s = 'supercalifragilisticexpialidocious'
>>> len(s)
34


串列List(mutable),string享有共同操作
跟字元陣列一樣有正負號的引數,也可以用加號連接,用星號來複製,len來偵測長度
不一樣的是他的數值可以被改變
>>> cubes = [1, 8, 27, 65, 125] # something's wrong here
>>> 4 ** 3 # the cube of 4 is 64, not 65!
64
>>> cubes[3] = 64 # replace the wrong value
>>> cubes
[1, 8, 27, 64, 125]

可以形成二維
>>> a = ['a', 'b', 'c']
>>> n = [1, 2, 3]
>>> x = [a, n]
>>> x
[['a', 'b', 'c'], [1, 2, 3]]
>>> x[0]
['a', 'b', 'c']
>>> x[0][1]
'b'

list還有下列函式可以使用
>>> a = [1,4,2,6]
>>> a.append(3) # 增加數值
>>> a
[1, 4, 2, 6, 3]
>>> a.remove(4) # 移除數值
>>> a
[1, 2, 6, 3]
>>> a.pop() # 移除最後一位的數值
3
>>> a
[1, 2, 6]
>>> a.sort() # 排序
>>> a
[1, 2, 6]
>>> a.reverse() # 順序顛倒
>>> a
[6, 2, 1]
>>>
>>> a.index(1) # 列出數值6index
2
>>> del a[0] # 移除引數0
>>> a
[2, 1]
>>>


List 也可以當作queues來用
>>> from collections import deque
>>> queue = deque(["Eric", "John", "Michael"])
>>> queue.append("Terry") # Terry arrives
>>> queue.append("Graham") # Graham arrives
>>> queue.popleft() # The first to arrive now leaves
'Eric'
>>> queue.popleft() # The second to arrive now leaves
'John'
>>> queue # Remaining queue in order of arrival
deque(['Michael', 'Terry', 'Graham'])

list還有更多的延伸功能,可以看一下這裡https://docs.python.org/3/tutorial/datastructures.html
5.1.1-5.1.4

Range()
代表由0開始到i-1
>>> for i in range(5):
... print(i)
...
0
1
2
3
4

如果range裡面有三個變數,最後一個表示間隔
range(5, 10)
5 through 9

range(0, 10, 3)
0, 3, 6, 9

range(-10, -100, -30)
-10, -40, -70


Tuple (immutable)
tuple內的數值是不可被改變的,可以用分號或是括號來表示
>>> t = 123,456,'hihi'
>>> t[1]
456
>>> t[1] = 123

Traceback (most recent call last):
File "<pyshell#2>", line 1, in <module>
t[1] = 123
TypeError: 'tuple' object does not support item assignment
>>> t
(123, 456, 'hihi')
>>>

因為tuple是不可變動的,所以要對tuple做變動的話,要先將其轉成list
>>> t = 2,5,4,8,6
>>> t
(2, 5, 4, 8, 6)
>>> t.sort()

Traceback (most recent call last):
File "<pyshell#14>", line 1, in <module>
t.sort()
AttributeError: 'tuple' object has no attribute 'sort'
>>> t1 = list(t)
>>> t1.sort()
>>> t1
[2, 4, 5, 6, 8]
>>>

其他更多有關tuple的資訊可以看這http://openhome.cc/Gossip/Python/TupleType.html


Sets無序群集
其牽涉到物件相等性(hashable),要建立一個set必須用{}
An object is hashable if it has a hash value which never changes during its lifetime (it needs a __hash__() method), and can be compared to other objects (it needs an __eq__() or __cmp__() method). Hashable objects which compare equal must have the same hash value.
Hashability makes an object usable as a dictionary key and a set member, because these data structures use the hash value internally.
>>> basket = {'apple', 'orange', 'apple', 'pear', 'orange', 'banana'}
>>> print(basket) # show that duplicates have been removed
{'orange', 'banana', 'pear', 'apple'}
>>> 'orange' in basket # fast membership testing
True
>>> 'crabgrass' in basket
False

>>> # Demonstrate set operations on unique letters from two words
...
>>> a = set('abracadabra')
>>> b = set('alacazam')
>>> a # unique letters in a
{'a', 'r', 'b', 'c', 'd'}
>>> a - b # letters in a but not in b
{'r', 'd', 'b'}
>>> a | b # letters in either a or b
{'a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'}
>>> a & b # letters in both a and b
{'a', 'c'}
>>> a ^ b # letters in a or b but not both
{'r', 'd', 'b', 'm', 'z', 'l'}


Dict
其是將keyvalue對應的物件,也是hashable,可用list(d.keys())sorted(d.keys())
>>> tel = {'jack': 4098, 'sape': 4139}
>>> tel['guido'] = 4127
>>> tel
{'sape': 4139, 'guido': 4127, 'jack': 4098}
>>> tel['jack']
4098
>>> del tel['sape']
>>> tel['irv'] = 4127
>>> tel
{'guido': 4127, 'irv': 4127, 'jack': 4098}
>>> list(tel.keys())
['irv', 'guido', 'jack']
>>> sorted(tel.keys())
['guido', 'irv', 'jack']
>>> 'guido' in tel
True
>>> 'jack' not in tel
False

其他更多有關setdict的範例可以看這5.6
https://docs.python.org/3/tutorial/datastructures.html

因為python有這麼方便的listtuple,使用者可以更方便的操控資料型態,把時間用在刀口上!!!!




2014年10月24日 星期五

wxpython thread

最近寫python需要程式一直在迴圈裡面跑
如果用while true的話會當機,沒有辦法按下停止鍵
看了下面兩個非常好的reference來練習一下怎麼寫wxpython thread

Reference :


wxpython下有三個最安全的方式來寫thread
wx.PostEvent
wx.CallAfter
wx.CallLater

wx.PostEvent是最低階的方式,那那那那就先用它來寫寫看吧!!!!!

這個練習是使用者按下start,表示開始執行另一個thread,然後右邊會反覆出現紅色與綠色的按鍵還有說明,最下面顯示這個迴圈已經被跑了幾次,每次跑的時候先從txt中讀出上次已經跑的次數,然後再繼續累加(所以要先在同一個資料夾下面準備一個test_cnt.txt的檔案),順便練習讀寫file還有把file放在textctrl中顯示,按下stop則停止這個thread

wxglade建立好視窗之後要加入 from threading import Thread


這邊寫thread最主要的關鍵就是EVT_RESULT_ID


wx.frame中再用ResultEvent來跟thread溝通



wx.Frame中如果使用者按下start,則會連到thread class來執行run function


run function,先把txt中的值讀出來,int()string轉成int來累加,利用wx.PostEvent(self._notify_window,ResultEvent("Green")) 來告訴wx.Frame classGUI上要做甚麼變化,如果使用者按下STOP則會傳到abort,然後傳到run中停止執行緒




test.py
import wx

# begin wxGlade: dependencies
import gettext
# end wxGlade

# begin wxGlade: extracode
# end wxGlade

############### Definitions ###############
from threading import Thread
import time
import os
###########################################

############### Threads #######################

# Define notification event for thread completion
EVT_RESULT_ID = wx.NewId()

def EVT_RESULT(win, func):
    """Define Result Event."""
    win.Connect(-1, -1, EVT_RESULT_ID, func)

class ResultEvent(wx.PyEvent):
    """Simple event to carry arbitrary result data."""
    def __init__(self, data):
        wx.PyEvent.__init__(self)
        self.SetEventType(EVT_RESULT_ID)
        self.data = data

class WorkerThread(Thread):
    def __init__(self,notify_window):
        Thread.__init__(self)
        self._notify_window = notify_window
        self._want_abort = 0
        self.start()

    def run(self):
        
        print("Read test_cnt.txt ")
        fread = file('test_cnt.txt','r')
        while True:           
            text = fread.readline()
            if len(text) == 0:
                break;
            print text
            cnt = int(text)
        fread.close()

        while True:
            time.sleep(1)
            if self._want_abort:
                wx.PostEvent(self._notify_window,ResultEvent(None))
                return

            wx.PostEvent(self._notify_window,ResultEvent("Green"))
            time.sleep(1)
            wx.PostEvent(self._notify_window,ResultEvent("Red"))
            time.sleep(1)
            fwrite = file('test_cnt.txt','w')
            cnt += 1                    
            fwrite.write("%s"%cnt)
            fwrite.close()
            time.sleep(1)
            wx.PostEvent(self._notify_window,ResultEvent("cnt"))

            
    def abort(self):
        self._want_abort = 1
        
################################################

class MyFrame(wx.Frame):
    def __init__(self, *args, **kwds):
        # begin wxGlade: MyFrame.__init__
        kwds["style"] = wx.DEFAULT_FRAME_STYLE
        wx.Frame.__init__(self, *args, **kwds)
        self.window_1 = wx.SplitterWindow(self, wx.ID_ANY, style=wx.SP_3D | wx.SP_BORDER)
        self.window_1_pane_1 = wx.Panel(self.window_1, wx.ID_ANY)
        self.start = wx.Button(self.window_1_pane_1, wx.ID_ANY, _("Start"))
        self.stop = wx.Button(self.window_1_pane_1, wx.ID_ANY, _("Stop"))
        self.window_1_pane_2 = wx.Panel(self.window_1, wx.ID_ANY)
        self.light = wx.Button(self.window_1_pane_2, wx.ID_ANY, _(""))
        self.status = wx.StaticText(self.window_1_pane_2, wx.ID_ANY, _("Status\n"))
        self.cnt = wx.TextCtrl(self.window_1_pane_2, wx.ID_ANY, "")

        self.__set_properties()
        self.__do_layout()
        # end wxGlade

        ################# init function ##################
        rd_log = open(os.path.join('', 'test_cnt.txt'), 'r')
        self.cnt.SetValue(rd_log.read())
        rd_log.close()

        ################# function binding ###############
        self.Bind(wx.EVT_BUTTON,self.EVTSTART,self.start)
        self.Bind(wx.EVT_BUTTON,self.EVTSTOP,self.stop)
        EVT_RESULT(self,self.updateDisplay)
        self.worker = None
        ###################################################


        ################# function binding ###############
    def EVTSTART(self,event):
        print("Start testing")
        self.worker = WorkerThread(self)
        

    def EVTSTOP(self,event):
        print("End testing")
        self.worker.abort()

    def updateDisplay(self,event):
        if event.data is "Green":
            self.light.SetBackgroundColour(wx.Colour(0, 255, 127))
            self.status.SetLabel('Green')

        if event.data is "Red":
            self.light.SetBackgroundColour(wx.Colour(255, 0, 61))
            self.status.SetLabel('Red')

        if event.data is "cnt":
            rd_log = open(os.path.join('', 'test_cnt.txt'), 'r')
            self.cnt.SetValue(rd_log.read())
            rd_log.close()
        ###################################################

    def __set_properties(self):
        # begin wxGlade: MyFrame.__set_properties
        self.SetTitle(_("Test"))
        self.start.SetMinSize((100, 80))
        self.stop.SetMinSize((100, 80))
        self.window_1_pane_1.SetMinSize((192, 257))
        self.light.SetMinSize((100, 40))
        self.window_1_pane_2.SetMinSize((188, 257))
        # end wxGlade

    def __do_layout(self):
        # begin wxGlade: MyFrame.__do_layout
        sizer_2 = wx.BoxSizer(wx.VERTICAL)
        sizer_5 = wx.BoxSizer(wx.VERTICAL)
        sizer_3 = wx.BoxSizer(wx.HORIZONTAL)
        sizer_4 = wx.BoxSizer(wx.VERTICAL)
        sizer_4.Add(self.start, 0, wx.LEFT | wx.TOP | wx.BOTTOM, 20)
        sizer_4.Add(self.stop, 0, wx.LEFT | wx.TOP, 20)
        sizer_3.Add(sizer_4, 1, wx.EXPAND, 0)
        self.window_1_pane_1.SetSizer(sizer_3)
        sizer_5.Add(self.light, 0, wx.LEFT | wx.TOP, 40)
        sizer_5.Add(self.status, 0, wx.LEFT | wx.RIGHT | wx.TOP | wx.ALIGN_CENTER_HORIZONTAL, 40)
        sizer_5.Add(self.cnt, 0, wx.TOP | wx.ALIGN_CENTER_HORIZONTAL, 30)
        self.window_1_pane_2.SetSizer(sizer_5)
        self.window_1.SplitVertically(self.window_1_pane_1, self.window_1_pane_2)
        sizer_2.Add(self.window_1, 1, wx.EXPAND, 0)
        self.SetSizer(sizer_2)
        sizer_2.Fit(self)
        self.Layout()
        # end wxGlade

# end of class MyFrame
if __name__ == "__main__":
    gettext.install("app") # replace with the appropriate catalog name

    app = wx.PySimpleApp(0)
    wx.InitAllImageHandlers()
    Test = MyFrame(None, wx.ID_ANY, "")
    app.SetTopWindow(Test)
    Test.Show()
    app.MainLoop()



如果用callafter則如下
import wx

# begin wxGlade: dependencies
import gettext
# end wxGlade

# begin wxGlade: extracode
# end wxGlade

############### Definitions ###############
from threading import Thread
from wx.lib.pubsub import Publisher
import time
import os
###########################################

############### Threads #######################

class WorkerThread(Thread):
    def __init__(self,notify_window):      
        Thread.__init__(self)
        self._notify_window = notify_window
        self._want_abort = 0
        self.start()

    def run(self):
        
        print("Read test_cnt.txt ")
        fread = file('test_cnt.txt','r')
        while True:           
            text = fread.readline()
            if len(text) == 0:
                break;
            print text
            cnt = int(text)
        fread.close()

        while True:
            time.sleep(1)
            if self._want_abort:
                wx.CallAfter(Publisher().sendMessage, "update", None)
                return
            wx.CallAfter(Publisher().sendMessage, "update", "Green")
            time.sleep(1)
            wx.CallAfter(Publisher().sendMessage, "update", "Red")
            time.sleep(1)
            fwrite = file('test_cnt.txt','w')
            cnt += 1                    
            fwrite.write("%s"%cnt)
            fwrite.close()
            time.sleep(1)
            wx.CallAfter(Publisher().sendMessage, "update", "cnt")
    
    def abort(self):
        self._want_abort = 1

################################################

class MyFrame(wx.Frame):
    def __init__(self, *args, **kwds):
        # begin wxGlade: MyFrame.__init__
        kwds["style"] = wx.DEFAULT_FRAME_STYLE
        wx.Frame.__init__(self, *args, **kwds)
        self.window_1 = wx.SplitterWindow(self, wx.ID_ANY, style=wx.SP_3D | wx.SP_BORDER)
        self.window_1_pane_1 = wx.Panel(self.window_1, wx.ID_ANY)
        self.start = wx.Button(self.window_1_pane_1, wx.ID_ANY, _("Start"))
        self.stop = wx.Button(self.window_1_pane_1, wx.ID_ANY, _("Stop"))
        self.window_1_pane_2 = wx.Panel(self.window_1, wx.ID_ANY)
        self.light = wx.Button(self.window_1_pane_2, wx.ID_ANY, _(""))
        self.status = wx.StaticText(self.window_1_pane_2, wx.ID_ANY, _("Status\n"))
        self.cnt = wx.TextCtrl(self.window_1_pane_2, wx.ID_ANY, "")

        self.__set_properties()
        self.__do_layout()
        # end wxGlade

        ################# init function ##################
        rd_log = open(os.path.join('', 'test_cnt.txt'), 'r')
        self.cnt.SetValue(rd_log.read())
        rd_log.close()

        ################# function binding ###############
        self.Bind(wx.EVT_BUTTON,self.EVTSTART,self.start)
        self.Bind(wx.EVT_BUTTON,self.EVTSTOP,self.stop)
        Publisher().subscribe(self.updateDisplay, "update")
        self.worker = None
        ###################################################


        ################# function binding ###############
    def EVTSTART(self,event):
        print("Start testing")
        self.worker = WorkerThread(self)
        

    def EVTSTOP(self,event):
        print("End testing")
        self.worker.abort()

    def updateDisplay(self,event):
        if event.data is "Green":
            self.light.SetBackgroundColour(wx.Colour(0, 255, 127))
            self.status.SetLabel('Green')

        if event.data is "Red":
            self.light.SetBackgroundColour(wx.Colour(255, 0, 61))
            self.status.SetLabel('Red')

        if event.data is "cnt":
            rd_log = open(os.path.join('', 'test_cnt.txt'), 'r')
            self.cnt.SetValue(rd_log.read())
            rd_log.close()
        ###################################################

    def __set_properties(self):
        # begin wxGlade: MyFrame.__set_properties
        self.SetTitle(_("Test"))
        self.start.SetMinSize((100, 80))
        self.stop.SetMinSize((100, 80))
        self.window_1_pane_1.SetMinSize((192, 257))
        self.light.SetMinSize((100, 40))
        self.window_1_pane_2.SetMinSize((188, 257))
        # end wxGlade

    def __do_layout(self):
        # begin wxGlade: MyFrame.__do_layout
        sizer_2 = wx.BoxSizer(wx.VERTICAL)
        sizer_5 = wx.BoxSizer(wx.VERTICAL)
        sizer_3 = wx.BoxSizer(wx.HORIZONTAL)
        sizer_4 = wx.BoxSizer(wx.VERTICAL)
        sizer_4.Add(self.start, 0, wx.LEFT | wx.TOP | wx.BOTTOM, 20)
        sizer_4.Add(self.stop, 0, wx.LEFT | wx.TOP, 20)
        sizer_3.Add(sizer_4, 1, wx.EXPAND, 0)
        self.window_1_pane_1.SetSizer(sizer_3)
        sizer_5.Add(self.light, 0, wx.LEFT | wx.TOP, 40)
        sizer_5.Add(self.status, 0, wx.LEFT | wx.RIGHT | wx.TOP | wx.ALIGN_CENTER_HORIZONTAL, 40)
        sizer_5.Add(self.cnt, 0, wx.TOP | wx.ALIGN_CENTER_HORIZONTAL, 30)
        self.window_1_pane_2.SetSizer(sizer_5)
        self.window_1.SplitVertically(self.window_1_pane_1, self.window_1_pane_2)
        sizer_2.Add(self.window_1, 1, wx.EXPAND, 0)
        self.SetSizer(sizer_2)
        sizer_2.Fit(self)
        self.Layout()
        # end wxGlade

# end of class MyFrame
if __name__ == "__main__":
    gettext.install("app") # replace with the appropriate catalog name

    app = wx.PySimpleApp(0)
    wx.InitAllImageHandlers()
    Test = MyFrame(None, wx.ID_ANY, "")
    app.SetTopWindow(Test)
    Test.Show()
    app.MainLoop()