2009年8月29日 星期六

Python Compiler (cx_freeze) for Linux

SourceForge下載: http://sourceforge.net/projects/cx-freeze/files/

Projects http://cx-freeze.sourceforge.net/


# wget cx_Freeze-4.1.tar.gz
# tar xzvf cx_Freeze-4.1.tar.gz
# cd cx_Freeze-4.1

記得看一下說明檔!!
# cat README.txt
------------
Please see cx_Freeze.html for documentation on how to use cx_Freeze.

To build:

python setup.py build
python setup.py install

On Windows I have used the MinGW compiler (http://www.mingw.org)

python setup.py build --compiler=mingw32
python setup.py build --compiler=mingw32 install
------------
安裝
# python setup.py build
# python setup.py install

參考一下範例 samples/
[advanced] [matplotlib] [relimport] [simple] [wx]

測試-先來個簡單的
# cd samples/simple
# ls 看一下有什麼東西
hello.py setup.py 只有二個檔案,內容都很容易懂的

setup.py 內容
------------
# A very simple setup script to create a single executable
#
# hello.py is a very simple "Hello, world" type script which also displays the
# environment in which the script runs
#
# Run the build process by running the command 'python setup.py build'
#
# If everything works well you should find a subdirectory in the build
# subdirectory that contains the files needed to run the script without Python

from cx_Freeze import setup, Executable

setup(
name = "hello",
version = "0.1",
description = "Sample cx_Freeze script",
executables = [Executable("hello.py")])

------------

測試編譯
# python setup.py build
# ls 看一下多出什麼東西
[build] hello.py setup.py 多出一個 build的目錄
# cd build/
# ls
[exe.linux-x86_64-2.5] 這個目錄的名稱會依使用的核心作命名

# cd exe.linux-x86_64-2.5
# ls -l
-rw-r--r-- 1 root root 41416 2009-08-29 12:34 array.so
-rwxr-xr-x 1 root root 11888 2009-08-29 12:34 hello 編譯好的檔案
-rw-r--r-- 1 root root 42112 2009-08-29 12:34 itertools.so
-rw-r--r-- 1 root root 1473760 2009-08-29 12:34 libpython2.5.so.1.0
-rw-r--r-- 1 root root 74373 2009-08-29 12:34 library.zip
-rw-r--r-- 1 root root 23352 2009-08-29 12:34 zlib.so

ps. 除了hello是剛才測試後的執行檔,其它的都是必須的不能刪除
ps. 記得如果要拷貝到其它地方執行,其它的檔案都要拷貝才能正確執行

# ./hello 測試編譯好的檔案是否有正常執行

ps. 範例中的項目最好都去看一下setup.py
例. [relimport] setup.py 一看就明白,自制模組要如何放置

Python Compiler (freeze) for Linux

資料來源:http://wiki.python.org/moin/Freeze

安裝套件: apt-get install python2.5-examples
套件路徑: /usr/share/doc/python2.5/examples/Tools/freeze/freeze.py
指令參數: python freeze.py -h

測試編譯: python /path/to/freeze.py [參數] 編譯檔名.py

# python /path/to/freeze.py -o dist test1.py
# cd dist
# make
測試編譯後的linux執行檔
# ./test1

---
錯誤提示:
缺少python2.6/config/config.c.in
安裝以下套件即可
apt-get install python2.6-dev

錯誤提示:
/usr/lib/python2.6/config/libpython2.6.a(posixmodule.o): In function `posix_tmpnam':
(.text+0x783): warning: the use of `tmpnam_r' is dangerous, better use `mkstemp'
/usr/lib/python2.6/config/libpython2.6.a(posixmodule.o): In function `posix_tempnam':
(.text+0x865): warning: the use of `tempnam' is dangerous, better use `mkstemp'
config.o:(.data+0x98): undefined reference to `init_warnings'
collect2: ld returned 1 exit status
make: *** [client] Error 1

安裝以下套件即可
apt-get install ?????

---
安裝 psyco 加速模組
# wget http://downloads.sourceforge.net/project/psyco/psyco/1.6/psyco-1.6-linux.i386-2.5.tar.gz?use_mirror=nchc
# tar xzvf psyco-1.6-linux.i386-2.5.tar.gz
# cd psyco-1.6
# cp -rf psyco /usr/lib/python2.5/site-packages/

#加入 import psyco
try:
import psyco
psyco.profile()
except:
pass

加入psyco模組,再用freeze作編譯,正常可執行

2009年8月11日 星期二

正規表示式2

引用 http://fannys23.pixnet.net/blog/trackback/e150b26b3d/15367167


檢查工具 http://osteele.com/tools/rework/

1. 對正規表示式來說,任意字元是以點 (.) 表示。
e.g.
a...e 表示 a 與 e 之間有任意三個字元
ae←比對失敗
a12e←比對失敗,因為不足三個字元
abcde←比對成功

2. 中括號中表示指定特定的字元,若其中一個符合則符合
e.g.
a[abc]e
比對成功的例子: aae, abe, ace
比對失敗的例子: aze

3. 小寫的檢查: a-z,大寫的檢查: A-Z,數字的檢查: 0-9
e.g.
a[0-9a-zA-Z]e
在 a 與 e 間插入多個英數字或插入一個以上的特殊符號外,其他都符合規則

4. 在中括號之中的點 (.) ,僅代表一個點。
e.g.
a[.]e
只有 a.e 符合

5. 符號 ^ 在第一個字元出現時有 not 的意思
e.g.
a[^0-9a-zA-Z]e 表示英數字以外的符號符合此項比對

6. 符號 ^ 在第一個字元以外的地方出現,代表 ^ 本身這個字
e.g.
a[0-9^a-zA-Z]e 表示 a 和 e 間出現一個 ^ 或一個英數字均符合

7. 修飾詞:
星號 (*) 可用來代表零或多個
e.g.
a.*z 若字詞頭為 a 尾為 z 則符合
ab*z 若字詞頭為 a 尾為 z ,且中間出現一個以上的 b 則符合
ab.*z 字詞頭為 ab 尾為 z 則符合

問號 (?) 代表零個或一個
w.?e
符合的範例:we、wie
不符合的範例:willie

加號 (+) 代表一個或多個
e.g.
a.+z 在 a 和 z 之間出現一個或以上的字元即符合

若希望在 a 與 z 之間有一個以上非英文大寫的任意字元,
寫法為: a[^A-Z]+z

8. 大括號用來精確比對前一個字
ab{5}z ←僅 abbbbbz 符合
ab{1,5}z ←表示 b 出現最少一次、最多五次
a[A-Z]{1,5}z ←中間可以有一到五個大寫英文字

9. 意義相同的正規表示式:
b{1,} = b+
b{0,} = b*

10. 逸出字元前要加上反斜線
a\.b
a\[b
a\\b

11. 群組(grouping): 用小括號包起來
a(abc)*z ←表示 a 開頭、z 結尾,中間出現任意次數的 "abc"
另外也有記憶小括號的功能
e.g.
import re
m = re.search('it is (fine (today))', 'it is fine today')
m.group(0)
m.group(1)
m.group(2)
#以上程式會依續印出完整字串、左起第一組小括號、第二組小括號

12. 較短的表示方式:
http://www.amk.ca/python/howto/regex/
\w = [a-zA-Z0-9_]
\s = [\t\n \r\f\v]
\d = [0-9]      ←所以 IP 比對可以改寫成 \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}
            還可以再縮寫成 \d{1,3}(\.\d{1,3}){3}

大寫則有反義的用途,
例如 \D 是非數字,\W 代表非英數字、\s 代表非空白字元

13. 字和空白之間的交會點是 \b
因此 "Will and Willie are good friends."
可以利用 Will\b 找出 Will (以免同時也比對到 Willie)

14. 正規表示式預設有「貪多」的特性
import re
reg = re.search("t.*d", "today is fine")
reg.group()

這樣的搜尋會一路找到結尾、再找回來、才取出 tod,
會造成效能上的耗費,因此有不貪多演算法,
\.*? ←代表抓取任意字元、任意次數、不貪多
\.+? ←代表抓取任意字元、一次以上、不貪多

不貪多演算法的說明
http://www.gais.com.tw/article.php?u=DeeR&i=20080225

15. 把沒有明顯分隔符號的字串切割重組
e.g.
import re
text = "willie123good456"
"".join(re.split(r"\d+", text))

16. 使用其他人寫好的套件剖析 XML 與 HTML

HTML:
Beautiful Soup
http://www.crummy.com/software/BeautifulSoup/

Parsing HTML 的說明
http://www.crummy.com/software/BeautifulSoup/documentation.html#Parsing%20HTML

XML:
ElementTree
http://effbot.org/zone/element-index.htm
Parsing XML 的說明
http://docs.python.org/lib/module-xml.etree.ElementTree.html



【實作練習: 剖析 log 中異常的 IP】
#假設 IP 為 200 開頭的是異常 IP
#!/usr/bin/python

import re
f = open('/tmp/auth.log')
for i in f:
regex = re.search(r'200\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}', i)
if regex:
print regex.group()
f.close()

#re.search 表示比對正規表示式與輸入結果
#第一個參數是正規表示式,第二個是輸入內容
#regex.group() 預設參數是 0

tips:
小括號包起來的東西在 python 裡會被記憶,
因此若只想取 ip 最後一段,可改寫如下:

import re
f = open('/tmp/auth.log')
for i in f:
regex = re.search(r'200\.[0-9]{1,3}\.[0-9]{1,3}\.([0-9]{1,3})', i)
#加上小括號
if regex:
print regex.group(1)
#加上小括號所出現的 index (從 1 開始算)
f.close()



【實作練習:分析 log 檔中的非法使用者想入侵的帳號】

#!/usr/bin/python

import re
f = open('/tmp/auth.log')
for i in f:
regex = re.search(r'Invalid user ([^ ]+) from ([^ ]+)', i)
if regex:
print regex.group(1) + " => " + regex.group(2),
f.close()



【實作練習:分析 log 檔中的非法使用者想入侵的帳號 (改善執行效能)】

#!/usr/bin/python

import re
f = open('/tmp/auth.log')
rec = re.compile(r'Invalid user ([^ ]+) from ([^ ]+)')
for i in f:
regex = rec.search(i)
if regex:
print regex.group(1) + " => " + regex.group(2),
f.close()



【實作練習:分析 log 檔中的非法使用者想入侵的帳號 (縮短正規表示式)】

#!/usr/bin/python

import re
f = open('/tmp/auth.log')
rec = re.compile(r'Invalid user (\w+) from ([^ ]+)')
for i in f:
regex = rec.search(i)
if regex:
print regex.group(1) + " => " + regex.group(2),
f.close()



【實作練習:取出 HTML 的部分內容】

from BeautifulSoup import BeautifulSoup
f = open('test.htm')
html = f.read()
f.close()
soup = BeautifulSoup(html)
soup.html.body.span.string         #取出span標籤內夾記的內容
soup.html.body.a.string          #預設會取出第一個找到的 a 標籤夾記的內容
soup.html.body('div')[1].a.string     #取得第二組 div 內的 a 標籤
soup.html.body.div.a['href'] #抓出 a 標籤中的屬性 href



【實作練習:取出 XML 的部分內容】(for python 2.5)

from xml.etree.ElementTree import XML
myxml = open('test.xml').read()
seek = XML(myxml)
seek.getchildren() #確認 seek 可找到哪些子節點
seek.find('staff').find('name').text #取出子節點 staff 中的 name 裡頭的內容
for i in seek.findall('staff'): #找出所有的 staff
print i.find('name').text #取出 staff 中的 name 內容

正規表示式1 regular expressions


出處 http://osteele.com/tools/rework/

For more information about how to use regular expressions, including examples, additional documentation, and additional tools, see:
Regular-Expressions.info (online)
RegExLib (online)
Jeffrey Freidl's Mastering Regular Expressions (Amazon)

Quick Reference:
. any character except newline. If DOTALL, matches newline.
^ the start of the string. In multiline, matches start of each line.
$ the end of the string or just before the last newline. In multiline, matches before each newline.
\d,\w,\s digit, word, or whitespace, respectively
\D,\W,\S anything except digit, word, or whitespace
\. a period (and so on for \*, \(, etc.)
[ab] characters a or b
[a-c] a through c
[^ab] any character except a or b
expr* zero or more repetitions of expr
expr+ one or more repetitions of expr
expr? zero or one repetition of expr
*?,+?,?? ...same as above, but as little text as possible
expr{m} m copies of expr
expr{m,n} between m and n copies of the preceding expression
expr{m,n}? ...but as few as possible
a|b either a or b
(expr) same as expr, but captures the match for use in \1, etc.
(?:expr) doesn't capture the match
(?=expr) followed by expr
(?!expr) not followed by expr

Rsync 參數說明


使用方式:
rsync [OPTION]... SRC [SRC]... [USER@]HOST:DEST
rsync [OPTION]... [USER@]HOST:SRC [DEST]
rsync [OPTION]... SRC [SRC]... DEST
rsync [OPTION]... [USER@]HOST::SRC [DEST]
rsync [OPTION]... SRC [SRC]... [USER@]HOST::DEST
rsync [OPTION]... rsync://[USER@]HOST[:PORT]/SRC [DEST]
rsync [OPTION]... SRC [SRC]... rsync://[USER@]HOST[:PORT]/DEST

參數說明: (網路上的中文說明好像都這份~~所以也不知道真正的出處在那。)

-h , --help 顯示rsync求助資訊.
--version 顯示rsync版本.
-v , --verbose 複雜的輸出訊息.
-q , --quiet 安靜模式,幾乎沒有訊息產生.常用在以cron執行rsync.
-I, --ignore-times 通常rsync為了加快速度會忽略同樣檔案大小且同樣存取時間點的檔案.可以透過此參數關閉此快速檢查.
--size-only rsync只檢查檔案大小是否改變,不管時間存取點是否改變.通常用在mirror,且對方時間不太正確時.
-c, --checksum 在傳送之前透過128bit的md4檢查碼來檢查所有要傳送的檔案.(會拖慢速度.)
-a, --archive archive mode 權限保存模式,相當於 -rlptgoD 參數.
很快速的保存幾乎所有的權限設定,除了硬式連結(透過-H設定).
-r, --recursive 複製所有下層的資料(遞迴)
-R, --relative 使用相對路徑.
如:
rsync foo/bar/foo.c remote:/tmp/ 在遠端產生/tmp/foo.c檔案
rsync -R foo/bar/foo.c remote:/tmp/ 在遠端產生/tmp/foo/bar/foo.c 檔案
-R, --no-relative 不使用相對路徑.
-b, --backup 目的地端先前已經存在的檔案在傳輸或刪除前會被備份.
--backup-dir=DIR 設定備份的資料夾.
--suffix=SUFFIX 指定備份的檔案名稱字尾形式(預設為~).
-K, --keep-dirlinks 接收方將連結到資料夾的檔案視為資料夾處理
-l, --links 複製所有的連結
-H, --hard-links 保留硬式連結
-p, --perms 保留檔案權限
-o, --owner 保留檔案擁有者(root only)
-g, --group 保留檔案群組
-D, --devices 保留device資訊(root only)
-t, --times 保留時間點
-n, --dry-run 不實際執行傳送,只顯示將會有的傳輸動作
-S, --sparse 嘗試去處理稀疏的檔案,讓這些檔案在目的端佔去較少的磁碟空間.
-W, --whole-file 複製所有的檔案,不額外作檢查.
--no-whole-file 關閉 --whole-file 參數
-x, --one-file-system 不要跨越檔案系統分界(只在一個檔案系統處理)
-B, --block-size=SIZE 強制透過rsync程式去比對修復block-sizeforce
-e --rsh=COMMAND 定義所使用的remote shell
--rsync-path=PATH 定義rsync在遠端機器存放資料的路徑
--existing 只比對更新目的端已經存在的檔案
--ignore-existing 忽略目的端已經存在的檔案(也就是不更新)
--delete 刪除傳送端已經不存在,而目的端存在的檔案
--delete-excluded 除了把傳送端已經不存在,而目的端存在的檔案刪除之外,也刪除 --exclude 參數所包含的檔案.
--delete-after rsync預設會在檔案傳送前進行相關刪除動作確保接收端有足夠的檔案空間,但可以透過 --delete-after 讓刪除動作在檔案傳送後再行刪除.
--ignore-errors 忽略任何錯誤既使是I/O error 也進行 --delete 刪除動作.
--max-delete=NUM 定義rsync不要刪除超過 NUM 個檔案.
--partial rsync若遇到傳輸過程中斷時,會把那些已經傳輸的檔案刪除.在某種狀況下保留那些部分傳送的檔案是令人高興的.你可以透過 --partial 參數達到這個目的.
--partial-dir=DIR 在 --partial 參數啟動時,你還可以定義rsync把那些部分傳送的檔案寫入定義的資料夾,而非直接寫入目的端.需要注意的是,此資料夾不應該被其他使用者可以寫入.(如:/tmp)
--force 當目的端資料夾被傳送端非資料夾名稱覆蓋時,強制rsync刪除資料夾,即使該資料夾不是空的.
--numeric-ids 不將傳送端檔案的uid及gid值,與目的端的使用者/群組進行配對.若傳送端並沒有uid及gid的對應名稱(如:原帳號群組被刪除的遺留檔案),或目的端沒有相對應的帳號/群組,保留數字型態的uid/gid
--timeout=TIMEOUT 設定 I/O 逾時的時間(秒). 超過這個秒數而沒有資料傳送,rsync將會結束.預設為0,也就是沒有定義逾時時間.
-T, --temp-dir=DIR 定義rsync在接收端產生暫時性的複製檔案時使用資料夾暫存.預設是直接在接收端資料夾直接產生暫存檔案.
--compare-dest=DIR 定義rsync在目的端建立資料夾來比對傳送過來的檔案.
--link-dest=DIR 與 --compare-dest 相同,但同時會針對無法改變的檔案建立硬式連結.
-z, --compress 壓縮模式,當資料在傳送到目的端進行檔案壓縮.
-P -P參數和 --partial --progress 相同.只是為了把參數簡單化.
-C, --cvs-exclude 排除那些通常不希望傳送的檔案.定義的方式與CVS傳送相同:
RCS SCCS CVS CVS.adm RCSLOG cvslog.* tags TAGS .make .state .nse_depinfo *~ #* .#* ,* _$* *$ *.old *.bak *.BAK *.orig *.rej .del-* *.a *.olb *.o *.obj *.so *.exe *.Z *.elc *.ln core .svn/ 符合以上條件的都會被忽略而不傳送.
--exclude=PATTER 符合PATTERN(規則表示式)樣式的檔案不進行傳送
--exclude-from=FILE 和--exclude參數相同,不過是把不進行傳送的檔案事先寫入某一檔案.執行時,透過此參數讓rsync讀取.(; #開頭的行列或空白行會被rsync忽略)
--include=PATTERN 定義rsync不要排除符合pattern樣式的檔案.
--include-from=FILE 和--include參數相同,只不過把要包含的檔案寫到某一檔案.
--files-from=FILE 把要傳送的檔案名稱都精確的寫入某一檔案,讓rsync讀取.
如: rsync -a --files-from=/tmp/foo /usr remote:/backup
-0 --from0 定義檔案所要讀取的檔案是null字元結尾.
--version 顯示版本訊息.
--daemon 定義rsync以daemon型態執行.
--no-detach 當以daemon型態執行時,不要進行分裂且變成背景程序.
--address=ADDRESS 定義所要連結(bind)的ip位址或是host名稱(daemon限定)
--config=FILE 定義所要讀取的設定檔rsyncd.conf位置(daemon限定) 預設值為 /usr/local/etc/rsyncd.conf
--port=PORT 定義rsyncd(daemon)要執行的port(預設為tcp 873)
--blocking-io 使用blocking I/O連結遠端的shell,如rsh , remsh
--no-blocking-io 使用non-blocking連結遠端的shell,如ssh (預設值)
--stats 顯示檔案傳送時的資訊狀態
--progress 顯示傳送的進度.(給檔案傳送時,怕無聊的人用的..)
--log-format=FORMAT 定義log的格式(在rsyncd.conf設定)
--password-file=FILE 從檔案讀取與遠端rsync伺服器連結的密碼
--bwlimit=KBPS 定義傳輸頻寬的大小(KBytes/秒)
--write-batch=FILE 把紀錄資料寫入一個檔案(給其他相同環境且相同需求的機器使用)
--read-batch=FILE 透過讀取紀錄檔案來進行傳輸.(檔案由 --write-batch 參數產生)
--checksum-seed=NUM 定義檔案 checksum-seed 的大小(byte)
-4 --ipv4 使用IPv4協定
-6 --ipv6 使用IPv6協定

2009年8月4日 星期二

Python 套件管理

http://sourceforge.net/projects/pythonpkgmgr/

Python Package Manager is a cross platform tool for Python to assist with the downloading and installation of python packages. Coded in Python, and using wxWidgets, this program is a GUI that drives easy_install and/or pip.




psyco python加速模組


#Download From:
#python 2.6 win32
# http://www.voidspace.org.uk/python/modules.shtml#psyco
#
#python 2.5 win32
# http://sourceforge.net/projects/psyco/files/
#
# psyco is a python accelerator which speeds up pysync by 33%

#說明網頁
#http://psyco.sourceforge.net/psycoguide/node8.html

#For larger applications, try:
import psyco
psyco.profile()

#------
try:
import psyco
psyco.profile()
except:
pass

#other import
from xxxx import *
import xxx,xxxx

#------
if __name__ == '__main__':
# Import Psyco if available
try:
import psyco
psyco.full()
except ImportError:
pass
# ...your code here...

#------
psyco.full()#對所有函數用psyco進行編譯
psyco.bind(myfunction1)#對選擇的函數用psyco進行編譯

g = psyco.proxy(f) #對函數 f用psyco進行編譯
g(args) #Psyco-accelerated call #編譯後 g函數速度會有提升
f(args) #regular slow call #f函數保持原來的調用速度

psyco.log # 用來紀錄log #Enable logging to a file named xxx.log-psyco by default, where xxx is the name of the

psyco.profile() # 可用來替代 psyco.full()

#------
轉貼:: http://www.cnpython.org/docs/300/p_240.html

使用時,在需要做效率優化的源文件前面加入以下兩句就一切OK了
import psyco
psyco.full()

psyco.profile()可以對大程序進行適當分析,以確定哪些函數最值得編譯。
psyco.log()函數用來記錄profile()得到的信息,下次就可以運行就能更快一點。
psyco.bind(myfunc)指定對函數myfunc進行編譯,可以做到比full()更精細的控制。
psyco.proxy(f)創建一個新的函數,它的代碼是由f編譯得到二進制碼。

import math, timeit, psyco

def TestA():
res, loopcnt = 0.0, 100
for i in range(loopcnt):
for j in range(loopcnt):
for k in range(loopcnt):
res = res + math.sin(i+j+k) # loopcnt^3 times

if __name__=='__main__':
TestB = psyco.proxy(TestA)
ta = timeit.Timer("TestA()", "from __main__ import TestA")
tb = timeit.Timer("TestB()", "from __main__ import TestB")
print("TestA(): %.2fs" % (ta.timeit(10)))
print("TestB(): %.2fs" % (tb.timeit(10)))

運行結果如下:
$ python test.py
TestA(): 15.84s
TestB(): 1.82s

很明顯,使用Psyco處理過的函數執行速度快了大約7~8倍,比Psyco作者宣稱的平均加速4倍的倍率更大些。
Psyco的工作原理類似JIT,只不過是on-the-fly的,對用戶而言基本透明。Psyco的主要缺點是耗費內存資源較多,在我看來不是什麼大問題,也許做網絡服務和企業應用的人才需要考慮這些吧。

tw.archive.ubuntu.com apt-get掛站處理方法

## source.list 將tw.archive.ubuntu.com取代為mirror.nttu.edu.tw

/etc/apt# vim sources.list
:1,$s/tw.archive.ubuntu.com/mirror.nttu.edu.tw/g


VIM字串搜尋與取代
s(substitute)指令可搜尋某行列範圍。
g(global)指令則可搜尋整個編輯緩衝區的資料。
s指令以第一個滿足該條件的字串為其取代的對象,若該行有數個滿足該條
件的字串,也僅能取代第一個,若想取代所有的字串則需加上g參數。
:1,$s/old/new/g 將檔案中所有的『old』改成『new』。
:10,20s/^/ / 將第10行至第20行資料的最前面插入5個空白。
:%s/old/new/g 將編輯緩衝區中所有的『old』改成『new』。