11 November, 2012
Non-convex function: Rastrigin
10 November, 2012
視覺化學習 Python 程式語言
20 September, 2010
用 Python 處理 doc 檔
到今天已經退伍一個禮拜了, 如果還在當兵的話, 現在應該穿著全副武裝還有不能防水的雨衣在救災吧 XD
不久前我用 Python 寫了一個小程式幫女友處理她的 doc 檔,底下是心得記錄。 基本上 doc 檔比純文字檔難處理,因為要用到 windows API, 不過這也還好,大多數的人都用 windows, 所以 Python 一定會有可用的函式庫,而網路上還可以找到幾個用 Python 處理 doc 檔的 範例。 另一個棘手的地方是,doc 檔的段落具有格式,比如字型大小、顏色、粗細、框線、上下標, 段落還可能有縮排,在處理段落時這些都要保留下來。 如果是純文字就不會有這個問題, 通常只需 string 的內建函式即可搞定,甚至不用動到 regex。 之前沒接觸過 windows API,(平常我都用 LaTeX 或是純文字檔) 要如何解決這個問題,一開始一點頭緒都沒有, 後來才想到,如果要保留格式的話,用類似滑鼠選取之後的複製、貼上就可以了, 查了一下 MSDN,果然有這兩個函式。
11 July, 2009
Python Idiom: Decorator II
def fibonacci(n): if n in (0, 1): return n return fibonacci(n-1) + fibonacci(n-2)
11 June, 2009
Python Idiom: Decorator I
def func1(): print "inside func1()" def func2(): print "inside func2()"
我們希望在呼叫 func1() 前顯示 Entering func1, 而在離開 func1() 後顯示 Exited func1, 對 func2() 的要求也是相同,只是把函式名字換成 func2, 最直接的方法是修改 func1 及 func2 的實作內容, 可是這樣做實在太累贅了, 有沒有辦法把 func1 跟 func2 當作物件, 自己寫一個額外的函式來「裝飾」這些物件? Python 語言中所提供的 decorator 語法可以幫我們達到這個目的 (decorator 就是裝飾者的意思)。 decorator 的使用語法如下
07 June, 2009
使用快取加速遞迴函式
f(n) = f(n-1)+f(n-2), f(0) = 0, f(1) = 1Fibonacci 的公式是遞迴的, 因為要計算 f(n) 需要上次及上上次計算的結果。 直接套定義就有下面的函式 (in Python)
def fib(n): if n in (0, 1): return n return fib(n-1) + fib(n-2)實際測試,會發現上面函式的執行效率非常差, 比方說我們要計算 f(5),套定義,要先計算 f(3) 跟 f(4), 可是要計算 f(4) 又要先知道 f(3) 跟 f(2), 也就是說實際上 f(3) 算了兩次,依此類推 f(2) 計算了三次, 如果 n 很大的話,計算 f(n) 就會重覆很多不必要的計算, 要解決這個問題不難,在函式中加入一個快取來記錄之前算過的值就可以了
09 April, 2009
命令列使用:ls、cmd 及 start
ls -t
總是要等好幾秒才會看到結果,
由於這個指令太常用了,
必須想一個替代方案才行,
我的解法是利用 windows 內建的 shell,
ls -t
對應的指令如下
cmd //c dir //b //O-d
cmd 就是 windows 內建的 shell,
選項 //c 表示執行完後面的指令就結束,
而 dir //b //O-d
就是我們想要 cmd 執行的指令,
dir 會列出目錄中的檔案及子目錄,
選項 //b
表示去掉標頭資訊,
//O-d
表示依最新日期排序,
如果不清楚 dir 的使用方法,
可以試試選項 //?
。
下面是兩者的所需的時間:
ls -t |
2.812 secs |
cmd //c |
0.157 secs |
差了 10 倍以上,ls -t 實在太慢了。 接下來介紹一個我自創的指令, 假設想要執行目前目錄下的最新檔案, 比方剛剛下載了一個 pdf 文件或是一個 jpg 檔, 那這一個檔案就是目前目錄的最新檔案, 利用前面介紹的指令再加上 start 就可完成這個動作:
start `cmd //c dir //b //O-d | sed -n 1p`
start 1.jpg
會以預設開啟副檔名為 jpg 的程式來開啟 1.jpg,
而
start 1.pdf
會以預設開啟副檔名為 pdf 的程式來開啟 1.pdf。
問題來了,要怎麼產生目錄下最新檔案的名稱呢?
前面介紹的指令會將目錄下所有檔案由新到舊排列,
但我們只想要第一個,怎麼做呢?
簡單,利用 sed -n 1p
即可。
眼尖的人還會發現 start
後面的字串被反引號
`
括起來,
這麼做的目的是先執行反引號中的指令以取得我們想要的檔名。
出個練習題,寫一個 bash function 假設名稱是 t,
使得 t i
會執行目前目錄下第 i 新的檔案。
答案如下:
function t() { arg=${1:-"1"} start "`cmd //c dir //b //O-d | sed -n \"${arg}p\"`" }
上面用到 ${1:-"1"}$
是 bash 特有的
Shell Parameter Expansion,
非常好用,之前我有舉過一個 例子。
31 March, 2009
分析遞迴結構
(A ((B (C D)) (E F)))根據括號的順序以產生下面的結果
(C D) (B (C D)) (E F) ((B (C D)) (E F)) (A ((B (C D)) (E F)))該怎麼做呢?
07 March, 2009
用 bash 及 mv 換檔名
a.vcproj -> a.vc9.vcproj b.vcproj -> b.vc9.vcproj a.vcproj -> c.vc9.vcproj其實只要用 bash 寫一個 for 迴圈就解決了
17 December, 2008
Python Idiom: sort
data = [2, 3, 4, 5, 1] data.sort()上述程式碼會將 data 的元素由小到大排序, 因為 sort() 是直接排序 data 的元素,而不是排序複製 data 的元素, 所以傳回值是 None 以避免困擾,如果要將排序過的資料傳給另一個序列要使用 sorted(),如
sorted_data = sorted(data)假設現在 data 改成如下
data = [(11, 5, 1000), (13, 4, 10), (17, 6, 100), (19, 5, 1) ]想要以 tuple 的第二、三、一個元素的大小做排序,該怎麼做?
28 November, 2008
Python Idiom: dictionary
d = dict(a=1, b=2, c=3) d = {'a': 1, 'b': 2, 'c': 3}第一種做法不用打括號,打字會稍微快一點, 如果要用兩個 list 分別當作 dictionary 的 keys 跟 values, 可以利用 zip() 這個函式,例如
names = ['a', 'b', 'c'] counts = [1, 2, 3] d = dict(zip(names, counts))
19 November, 2008
Python Idiom: map, filter
items = [1,2,3,4,5] result = [] for i in items: result.append(i*i)map 提供了另一種方法
def square(x): return x*x result = map(square, items)map 的第一個參數是函式,第二個參數是序列, 而傳回值則是將輸入的函式套用到輸入序列的每一項元素所形成的新序列。 其實還可以寫得更短
result = map(lambda x: x*x, items)上面例子中的 lambda x: x*x 定義了一個無名函式,效果就如同前面定義的 square()。
05 November, 2008
Python Idiom: in
for key in d: print key其中 d 的型態可以是 list, tuple, set, string, dictionary 等。 要檢查一個字串是否含有某子字串,通常會想到下面的做法
sentence = "fly me to the moon" if sentence.find("fly") != -1: print "successful"其實更好的方法是用 in
if "fly" in sentence: print "successful"是不是更好閱讀,打字也更快呢?
04 November, 2008
Python Idiom: join
items = ['red', 'blue', 'green', 'yellow'] result = '' for s in items: result += sPython 提供了一個更有效率的解法
result = ''.join(items)如果字串中間要用逗號跟空白做分隔時,只要改成
result = ', '.join(items)單括號內的字串就是隔開 items 元素的分隔物, 所以如果單括號內是空的,就表示沒有分隔物。 底下介紹上述技巧的應用
03 November, 2008
Python Idiom: list comprehensions
numbers = [1,2,3,4,5,6] squares = [] for n in numbers: if n % 2 == 0: squares.append(n*n)上述程式碼將 numbers 中是偶數的元素平方之後加到 squares。利用 list comprehensions 只要一行程式碼就可以完成目的。
squares = [n*n for n in numbers if n % 2 == 0]請注意程式的可讀性是不是並沒有因為程式碼的縮短而減少呢? 其實 list comprehensions 中可以有很多個 for 跟 很多個 if, 不過使用時要斟酌一下,如果真的有很多個 for 跟 if, 最好考慮使用一般的寫法,不然程式就會變得不易閱讀。
02 November, 2008
Python Idiom: enumerate
for item in items: print item但如果要同時把 item 的 index 也印出來,該怎麼做?
30 October, 2008
Python Idiom: tuple
tmp = a; a = b; b = tmp;而在 Python 中只要一行就可以解決了
a, b = b, a
22 October, 2008
使用命令列上傳 google 文件
相信很多人都會使用 Google Docs 來撰寫文件吧, 我則是拿它當作文件備份的工具,平常我會將一些想要記錄的事寫成純文字檔, 比如記錄機車加油的里程數,英文單字,還有買了那些東西,假設這三個檔案分別叫做 bike.txt, vocabulary.txt, buy.txt, 因為懶得登入找到文件再找到上傳的按鈕,我想要使用下面的命令列就好了:
google_docs bike.txt vocabulary.txt buy.txt
21 October, 2008
generating all vertices of a box
續之前產生 排列組合 的問題,無意間又發現了一個新的解法,先回顧問題一下, 如何產生下面的序列?
0000 1000 0100 1100 0010 1010 0110 1110 0001 1001 0101 1101 0011 1011 0111 1111