Showing posts with label Programming. Show all posts
Showing posts with label Programming. Show all posts

11 November, 2012

Non-convex function: Rastrigin

Convex optimization (凸最佳化)是最佳化理論中一個重要的分支, convex optimization 有一個很好的特性, 亦即如果 local minimum 存在的話則它必定是 global minimum。 一般的最佳化問題不一定可以被寫成凸最佳的問題, 所以會遇到存在很多 local minimum 的問題。 以下的 Rastrigin function 是一個例子

10 November, 2012

視覺化學習 Python 程式語言

對於初學程式語言的人來說,要在腦中想像程式執行可能不是一件簡單的事, 現在有一個網站 pythontutor 可以讓你用 step by step 的方式看到每一個敘述執行之後會發生什麼事,連 Python 語言創造者 Guido van Rossum 都說 Cool!

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

之前的部落格 介紹了 decorator 的基本概念及用法,本篇介紹 decorator 的兩個應用。 第一個例子是 幫函式加上快取
def fibonacci(n):
   if n in (0, 1):
      return n
   return fibonacci(n-1) + fibonacci(n-2)

11 June, 2009

Python Idiom: Decorator I

本文將介紹 Python Decorators 的用法,主要內容是根據我的理解部分改寫 Bruce Eckel 的好文 Decorators I: Introduction to Python Decorators 。假設我們有下面兩個函式
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

使用快取加速遞迴函式

大家都知道 Fibonacci 序列 吧, 公式很簡單
f(n) = f(n-1)+f(n-2),  f(0) = 0,  f(1) = 1
Fibonacci 的公式是遞迴的, 因為要計算 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

平常我都是用 MinGW 所提供的 MSYS 套件當作命令列系統, 可是遇到一個問題,每當我打 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 換檔名

JeffHung 寫了一篇文章介紹 用 find、sed、xargs 及 mv 換檔名,其實我還蠻常遇到這個問題的, 底下介紹我的做法。假設現在想要把下面第一欄的檔名換成第二欄的檔名
a.vcproj -> a.vc9.vcproj
b.vcproj -> b.vc9.vcproj
a.vcproj -> c.vc9.vcproj
其實只要用 bash 寫一個 for 迴圈就解決了

17 December, 2008

Python Idiom: sort

本文將介紹如何使用 sort(), 參考資料來自 Sorting Mini-HowTo, 首先介紹基本用法
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

這次將介紹 dictionary 的常見用法,底下是建立 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

這次我將介紹兩個跟 functional programming 有關的函式 map 及 filter。 假設我想把 list 中每一個元素平方之後放到一個新的 list,最直接的做法是
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

這次將介紹 in 這個關鍵字, 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

如果要將一個 list 中的所有字串接起來 ,一般的做法是
items = ['red', 'blue', 'green', 'yellow']

result = ''
for s in items:
    result += s
Python 提供了一個更有效率的解法
result = ''.join(items)
如果字串中間要用逗號跟空白做分隔時,只要改成
result = ', '.join(items)
單括號內的字串就是隔開 items 元素的分隔物, 所以如果單括號內是空的,就表示沒有分隔物。 底下介紹上述技巧的應用

03 November, 2008

Python Idiom: list comprehensions

寫程式時常常會遇到許多的 for 跟 if,如下面的範例
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

接續 上次 的文章,這次來介紹一個關於迴圈的技巧。 如果想要印出一個 list 的內容,Python 的標準做法是
for item in items:
     print item
但如果要同時把 item 的 index 也印出來,該怎麼做?

30 October, 2008

Python Idiom: tuple

推薦三篇 Python 好文給喜歡 Python 的人, 分別是 David Goodger 所寫的 Code Like a Pythonista: Idiomatic Python 和 David 所寫的 Python Tips, Tricks, and Hacks 還有 Rob Kinght 所寫的 Python Idioms and Efficiency。 之後我會將從這幾篇學到的技巧陸續列上來。 首先介紹 tuple 的用法, 在 C 語言如果要交換變數 a 跟 b 的值,一般的做法是 tuple 的用法, 在 C 語言如果要交換變數 a 跟 b 的值,一般的做法是
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

25 March, 2008

排列組合 in Python

還記得高中時的排列組合問題嗎? 比方說我有 d 個相同的球要放到 N 個位置, 位置沒有編號,總共有幾種放法呢?