PageRank



轉移公告

計劃把 http://blog.hoamon.info/ 文章全部轉移至 http://www.hoamon.info/blog/ 這裡,而本 Blogger 站台的文章近 500 篇,我預計在 2014-12-31 前移轉完畢,完成後 http://blog.hoamon.info/ 將只作代轉服務,一律把舊連結如 http://blog.hoamon.info/index.html 轉成 http://www.hoamon.info/blog/index.html ,敬請舊雨新知互相走告。

新文章只發佈在 http://www.hoamon.info/blog/

何岳峰 敬上

2007年3月27日 星期二

svn/cvs除了copy效率比copy快,還有其他的優點:備份及復原…

之前 debian 的版本控制伺服器發生過怪客入侵事件,而他們的解決之道是立即讓伺服器下線,並比對所有協助開發的程式設計師手邊的沙箱,藉此找出有問題的程式碼。因為每個人手頭都有一份全專案副本,所以有跡可尋。

如果是發生在 copy 來 copy 去的專案中,那要比對程式版本的差異就麻煩了,因為可能沒有工程師有所有的專案程式碼。這最常發生在使用「copy」概念的軟體專案中,他們使用元件化、模組化的概念來開發程式,Amon負責A元件、Bill負責B元件,這樣雖不會有衝突,但如果Amon掛了,搞不好還得找個人來重寫A元件。

所以如果你用了 svn/cvs ,你還有機會快速比對被怪的程式碼以及每個程設師會幫你備份1個專案。

使用svn/cvs的重要觀念:人的溝通才能花解程式碼的衝突

幾天前跟一個在軟體業界滿長時間的朋友談程式碼管理的技巧,他說:「小專案一定不用版本控制,而大專案也不一定要用。」

這原因出在他們有一個慘痛的教訓。因為一個程設師忽視其他程設師的錯誤修正,強制把他的patch檔送 VSS 儲存庫(我不是故意指名道姓的,因為事實上,他們是用 VSS),於是1個bug,兩個人解決,也就是等於沒人解決。所以他們衍生出使用版本控制器一定要用 lock 動作,單一檔同時間只允許1個程設師修改,而且不可以破壞別人建立的 lock 。這麼作,只是把 VSS 當作高級 cpoy 指令來用而已。

我跟這位朋友提到使用 svn/cvs 的一個重要觀念:每次 commit 前,要先作 update ,且要看看別人所修改的程式碼及註解,如果與自己的程式發生嚴重的邏輯衝突時,不是硬幹別人的程式,而是打個電話跟他聊聊。

如果軟體公司沒有正確地使用版本控制,而是使用老舊的copy思維。為此,他們會衍生出一種與 copy 相輔相成的工作模式:專業分工。把一個軟體專案元件化、模組化,切完再丟給工程師作,每個人專注自己的小區塊,出了問題自己解決,然後再找一位菜鳥程設師來作 SA ,時間到了,就跟大家要要程式碼,兜在一起跑。這麼作看似解決了程式碼衝突的問題,但也帶來新的問題:
  1. 程設師漠視團體的效益,專注自己的效益。
  2. 認為只要開幾次會,定下模組溝通的介面,就可以不再溝通了。
  3. 少了彼此學習的機會。
可是如果你是正確使用版本控制器的,舉個例子( http://chinesetrad.joelonsoftware.com/Articles/TheJoelTest.html )來說說:「約耳老兄在Excel 團隊時有個規定,每天要將專案編譯1次,且導致編譯失敗的人必須從此負責重新編譯的動作(作為處罰), 一直到有其他人出錯為止這是個讓人不要導致編譯失敗的好誘因同時是個讓大家輪流處理重新編譯的好方法這樣大家都會知道怎麼做。」

當你可以綜觀整個專案時,你可以了解模組之間的關係,可以看看別人的程式精華,可以少1個SA(或許軟體公司對這個比較心動),而你只是花1~3個小時,去學1個你未來都用得到的版本控制器,很划算吧!

等等,我聽到有人反應「如果公司不想讓所有人接觸整個專案呢」!這個例子我有遇到過,曾經就遇到一間公司要求1個工程師把商業邏輯都寫在資料庫的預存程序中,而另1個工程師則是撰寫網頁程式來呼叫這些預存程序,這公司希望產品不要讓1個工程師全把握住。遇到這種例子,就善用 subversion 的權限管理,把一個專案中的兩個模組設定1個只有A工程師可讀寫,另1個只有B工程師可讀寫。但我想,這個管 subversion 的人,該是公司老闆來,還是他美貌的秘書呢!

Why Blogging?

這問題的答案與「為什麼讀書」是一樣的。你認為讀書的目的是賺錢、受人尊重、有自信…嗎?都不是,讀書本身就是目的,就是收穫。

寫部落格時,你會整理你的想法,深度地檢視你的想法,這時你或許會發現「本以為的」就不再是那麼地直覺、自然了。你的想法在發佈的那一刻洗滌了。

如果你的想法未被自己洗乾淨,那還有可能被路過的遊客幫忙洗一洗, Blogging 真是棒呀!

2007年3月26日 星期一

sqlite3的資料備份及回復

因為我的系統從 fedora 改成 ubuntu 6.10 ,造成 trac 系統無法運作,它出現的錯誤訊息是:

Command failed: unsupported file format

查了一下,問題是出在 ubuntu 的 sqlite3 版本不夠新,所以無法讀取之前 fedora 的 db 檔。這問題不大,把 db 檔的資料 dump 出來,再用舊版本的 sqlite3 import 進去就行了。

$ sqlite3 xxx.db .dump > xxx.sql # 在 fedora 上執行 $ sqlite3 xxx.db < xxx.sql # 在 ubuntu 上執行

這樣你的 db 檔就可以給 trac 用啦。

誰還在用 copy 呀!

曾看過一個網友留言,說道他的小組才3個人而已,用不上 VSS(Visual SourceSafe) 之類的東西,他都是用 copy 的方式與其他人交換程式的。不曉得他這番話的重點是說 VSS 不好用,還是版本控制器不適合小組作業,只能用在大專案上。

從我認識了 cvs 及 subversion 後,就算是只有我自己在開發程式,如果不用版本控制器管理純文字格式文件的話,會覺得十分對不起自己。

想想看,一個程式檔你除了思考程式邏輯外,還要拿一份「記憶體」放置今天的算法與昨天算法在程式碼的差別,喔~饒了我吧!我的腦袋放不了那麼多東西了。

況且有那麼多的 open source 工具協助你,實在沒有理由不用版本控制器。想想看程式/文件寫了3個月後,你忽然覺得後悔了,想回復3天前放棄的演算法,你要拿出 xxx_070321.tgz、xxx_070322.tgz 出來,一個檔一個檔地找嗎?還是用 Trac + subversion 之類的工具,讓你可以點選
http://ptrac.hoamon.info/changeset/3 ,然後從這找出你想要的算法呢!!

嗨~朋友,我懇求你學一下 subversion 吧!別把你的青春放在這,多一點時間玩 online game 會比較好。

我的另一篇文章: 版本控制系統 svn(subversion)

2007年3月24日 星期六

Django0.96與MySQLdb之間的小問題

使用 0.96 版有一個小麻煩,在 ubuntu 上所編入的 MySQLdb 是 1.2.1g3 版,但 0.96 要求使用 1.2.1p2 以上版本,這事不難辦,重裝一個 MySQLdb 就好了,問題是出在手動安裝 MySQLdb 套件時,需要使用 MySQL-server 的 mysql_config 指令,這個程式是包在 devel 套件中時,在 ubuntu 中,它的名字叫 libmysqlclient15-dev ,在 fedora 中,它叫作 mysql-devel 。麻煩的地方就在這, mysql_config 與 mysql-devel 兩個字看起來沒關係,所以我花了一段時間,才找到應該要裝的是這個套件。詳細指令如下:

$ sudo apt-get install libmysqlclient15-dev
$ cd MySQLdb-1.2.2 ; # edit site.cfg; set mysql_config=/usr/bin/mysql_config
$ sudo python setup.py install

ExplorerCanvas:IE瀏覽器上的js修正檔

之前還信心滿滿地跟人家說,不會有人在瀏覽器上開發圖形函式庫呢~今天就被打巴掌了。

這個 ExplorerCanvas 程式也不算是讓 IE 瀏覽器上跑 2D 圖形運算的函式庫,它其實是一個讓 javascript 程設師能設計跨瀏覽器的 javascript 程式。為什麼要這樣作呢!原因就出在微軟喜歡用自己的方式來造輪子,所以其他的 Firefox 、 Opera 、 Safari 都支援相同的 tags 來完成 2D 的圖形運算,但 IE 用自己的 ActiveX 元件。

所以只要在你的網頁前頭先載入這個 ExplorerCanvas.js 檔,那麼你呼叫執行的 js 就不用分瀏覽器了。

下面是它的一些範例:

http://www.nchu-cm.com/examples/example3.html - 裡面的圖有4mb,請小心使用。
http://www.nchu-cm.com/examples/example2.html
http://www.nchu-cm.com/examples/example1.html

世界何其大,還是仔細研究過再說吧!

2007年3月23日 星期五

Google Code Search

有時候,一個小函式久沒用,會忘了它要有那些引數。最好的方法,就是找到範例,不需談原理,就是給我語法。但若是在 google 上 google ,常常會令人失望,因為程設師沒有為這個函式撰寫文件,所以找不到。

這時,你會發想,天下的 open source 何其多,程式碼都到那裡去了。隨便一個範例都找不到嗎!!

別氣餒, google 為你準備好了,就上 google 的 code search 吧!像是你忘了 Python 的 md5 函數怎麼用!就在搜尋框裡打 lang:python md5 就行啦!

Google所參加的組織

因為想要拿一些 google 開發的程式來用,所以到 code.google.com 看看,結果發現他們的團隊有參加幾個公益組織(或者是說基金會、委員會):

Pygments:程式碼變色的另一種方法

如果你喜歡 Python 多於 VIM 的話,那麼你還有 Pygments 可以用。感謝 Tib 提供的 style 檔。

首先請先安裝 pygments ,請用

# sudo easy_install Pygments-0.7.1-py2.4.egg

這樣你就多了一個 pygmentize 指令了。如果你想要把 pymail.py 變顏色,請下

# pygmentize -f html -O encoding=utf-8,linenos=1 -l python -o pymail.html pymail.py

所得到的 pymail.html 檔則是把 pymail.py 程式碼中的關鍵字作分類的動作,這樣還沒有上顏色喔~要上顏色的作法則是

# pygmentize -f html -S colorful -a div.highlight

這樣則會產生一個 css 語法的程式碼。如果你不喜歡 colorful ,你可以看看你的 /yourpath/Pygments-0.7.1-py2.4.egg/pygments/styles 資料夾下有那些 .py ,這些都可以用。如果還是不喜歡的話,可以參考一下 tib 的 style 檔,把它放到 /yourpath/Pygments- 0.7.1-py2.4.egg/pygments/styles 下,檔名則要命名為「 Class Name 去掉 Style 後全部小寫的英文字」。這樣你就可以用

# pygmentize -f html -S defaultsbt -a div.highlight

 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#!/usr/bin/python
import smtplib

def mkmail(toaddr, name, pwk, history):
fromaddr = 'powerkey@cams.wra.gov.tw'
subject = 'PowerKey of CAMS'
# Add the From: and To: headers at the start!
msg = ("From: %s\r\nTo: %s\r\nSubject: %s\r\n"
% (fromaddr, toaddr, subject))
msg += """**本信 由系統自動發送,請勿回覆本信**
=====================================

%s 先生/小姐:
感謝你的使用。密碼如下方連結:
http://www/PowerKey/showkey.html?powerkey=%s

密碼信寄送的歷史紀錄:
%s
""" % (name[0:3], pwk, history)

server = smtplib.SMTP('localhost')
server.set_debuglevel(0)
server.sendmail(fromaddr, toaddr, msg)
server.quit()

mkmail('hoamon@hoamon.info', '何岳峰', '11e4', 'history')

2007年3月22日 星期四

可怕的 VIM

每次在 blogger 上發表帶有程式碼的文章時,都感到十分麻煩。自己要作 space 轉 dash 的動作,還有變顏色。

但沒想到 VIM 就有一個指令可以讓文章變成網頁格式。

請把你編輯的文章調成你想要發佈的樣子,如行號顯示、顏色區別等,然後用 :TOhtml 指令即可。

下面就是一個 Python 程式碼轉出來的網頁結果:

 1 #!/usr/bin/python
2 # -*- coding: utf-8 -*-
3 import smtplib
4
5 def mkmail(toaddr, name, pwk, history):
6 fromaddr = 'powerkey@test.com.tw'
7 subject = 'PowerKey'
8 # Add the From: and To: headers at the start!
9 msg = ("From: %s\r\nTo: %s\r\nSubject: %s\r\n"
10 % (fromaddr, toaddr, subject))
11 msg += """**本信由系統自動發送,請勿回覆本信**
12 =====================================
13
14 %s 先生/小姐:
15 感謝你的使用。密碼如下方連結:
16 http://www/PowerKey/showkey.html?powerkey=%s
17
18 密碼信寄送的歷史紀錄:
19 %s
20 """ % (name[0:3], pwk, history)
21
22 server = smtplib.SMTP('localhost')
23 server.set_debuglevel(0)
24 server.sendmail(fromaddr, toaddr, msg)
25 server.quit()
26
27 mkmail('homon%2hoamoin.ino', '何岳峰', '11e4', 'history')

2007年3月21日 星期三

Python及PHP的公私鑰加密方法

昨天費了好大的一番勁,終於可以在 Python 中作公私鑰的處理,忙完了 Python 這邊,再往 PHP 去作,居然只花30分鐘。這最大的原因我想是出在一開始我完全不知道加解密該如何處理,所以我有些時間是花在私錀加解密上,而且 Python 這邊的模組還真是多,我試玩了 5 個,才找到我要的東西。分別是:
  1. python-crypto - 這個模組是基本模組,使用的函式太複雜了,不會用。
  2. ezPyCrypto - 這個簡單些了,但他作出來的公私鑰無法與其他程式相容(這一點,我也不知道為什麼)。
  3. SSLCrypto - 與 ezPyCrypto 是相同作者,而這個模組的效率比 ezPyCrypto 好。但一樣不能與其他程式相容。
  4. pyopenssl - 作者說他不欣賞 M2Crypto 與 SWIG 介接的方式,是的,我也不欣賞。但 pyopenssl 似乎是用 https 通訊上的,而我找不到加解密的用法。
  5. M2Crypto - 終於讓我找到了。但它有一大缺點。它底層是用 SWIG 來與 OpenSSL 介接的,而 SWIG 程式在 Windows 上非常難裝。
M2Crypto 在 ubunto 6.06.01 及 fedora core 5 中都有了。只是我還是用 PyPi 上的 0.17 版。而安裝方式是:
  • 先安裝 python2.4-pyrex 、 libssl-dev 、 swig 。
  • 到 m2crypto 資料夾執行 sudo python setup.py install
接下來,測試 M2Crypto 模組,因為我希望這個模組所用的公私鑰可與其他程式互動,所以用 openssl 來產生公私鑰。產生方法:

# openssl genrsa -out rsaprivate.pem 2048
# openssl rsa -in rsaprivate.pem -out rsapublic.pem -pubout -outform PEM

這樣我們就有兩支鑰匙了。接下我們用 Python with 私鑰 加密。

from M2Crypto import RSA

def test_encrypt(padding):
----msg="The magic words are squeamish ossifrage."
----priv=RSA.load_key('rsaprivate.pem')
----padding=eval('RSA.'+padding)
----ctxt=priv.private_encrypt(msg, padding)
----file = open(' c.txt', 'wb')
----file.write(ctxt)

if __name__ == '__main__':
----test_encrypt('pkcs1_padding')

我們得到了 c.txt 這個加密檔。好了,接下來,要到 Windows 去冒險了。

請先安裝 openssl.exe ,版本須大於 0.9.8 喔~
接下來設定 php.ini ,把 ;extension=openssl.dll 的註解拿掉,重新啟動 Apache2 。這樣你的 PHP 就多了 openssl 相關函式庫了。

接下來執行下面的 PHP 程式,它會用公鑰來解密,最後會得到「String decrypt : The magic words are squeamish ossifrage.」。恭喜你啦。公私鑰加解密就這麼簡單。

<?php
$fp=fopen ("rsapublic.pem","r");
$pub_key=fread($fp,8192);
fclose($fp);
$fp=fopen ("c.txt","r");
$crypttext=fread($fp,8192);
fclose($fp);
openssl_get_publickey($pub_key);
openssl_public_decrypt($crypttext,$newsource,$pub_key);
echo "String decrypt : $newsource\n";
?>

2007年3月17日 星期六

換書 or 賣書


錯買了一本書「ajax經典範例集」。內容盡是 AJAX.net 及 C# 程式範例。怪我網路購物前沒作好分析工作。翻了兩、三頁就看不下去了。誠徵有心人與我交換此書,如果你有博碩的 Ajax 與 Google Map API 入門實作 ,歡迎你與我交換,或者你願意用 200 元跟我買這本沒看幾頁的新書。

交易方式: 埔里面交。
有心人請寄 email 給我。

2007年3月15日 星期四

CMCLass: 派送問題(1)

受強烈地震之災,USA--A區有 12 軍事基地 毀損,被迫需搬遷至 B 區 12 軍事基地。搬遷成本與軍事基地間搬遷直線距離成正比

兩區的平面座標如下:
A區 X 座標 Y 座標
B區 X 座標 Y 座標
1 1130 863
1 1031 1206
2 1705 1283
2 1046 1000
3 1326 1736
3 1803 1809
4 975 825
4 1588 1821
5 1286 807
5 1300 1482
6 909 1143
6 1939 1228
7 1579 1608
7 1147 1703
8 1162 1118
8 1319 1254
9 876 1573
9 1300 1182
10 1198 1748
10 1817 1269
11 801 1134
11 1945 1605
12 956 1226
12 1349 1488

非常典型的 lp 問題,方程式也非常好設定。首先我們要列出這 a[12] 到 b[12] 的所有相對距離,共有 12 x 12 = 144 個,這也表示決策變數 Xij 有144個,當 Xij = 1 時,表示由 i 基地搬遷至 j 基地,當 Xij = 0 時,表示「沒事發生」。

所以目標函數就是所有相對距離 x 決策變數的總和。

接下來設定 25 條方程式:

all Xij >= 0

sum j=1~12 Xij = 1 對所有的 i 成立。(實在不知道該如何展現數學方程式,只好用口語的方式)

sum i=1~12 Xij = 1 對所有的 j 成立。(實在不知道該如何展現數學方程式,只好用口語的方式)

這樣就有 25 條方程式了。跑一下 lp 程式就可以得到答案。

那麼 Python 如何跑 lp 程式呢!首先請裝 GLPK 函數庫,這是由 gnu 組織開發的 linear programming toolkit ,功能還可以,但如果決策變數太多,有可能會跑不完。

理論上,你裝了 GLPK 後,就可以執行 lp 計算,但是直接用 GLPK 的話,必須用 mathprog 格式餵資料給 GLPK ,而這個格式太複雜了,所以我先去載入一個輸出 mathprog 格式的 Python 類別 pulp ,透過這個類別幫我控制 GLPK 函式庫。

以下是我的 Python 程式:

def caldest(From, To):
----from math import sqrt
----dest = []

----for start in From:
--------subdest = []
--------for end in To:
------------subdest.append(round(sqrt((start[0] - end[0])**2 + (start[1] - end[1])**2), 0))
--------dest.append(subdest)

----return dest

def optima(coef):
----from pulp import *
----(Dest, var, obj) = (coef, [], 0)
----prob = LpProblem("dest", LpMinimize)

----for i in xrange(len(Dest)):
--------var.append([])
--------for j in xrange(len(Dest[0])):
------------(str_i, str_j) = ("%03d" % (i + 1), "%03d" % (j + 1))
------------var[i].append(LpVariable("var"+str_i+'_'+str_j, 0, 1, LpInteger))
------------obj += Dest[i][j] * var[i][j]

----prob += obj, 'OBJ.'

----for i in xrange(len(Dest)):
--------st = 0
--------for j in xrange(len(Dest[0])):
------------st += var[i][j]
--------prob += st == 1

----for j in xrange(len(Dest[0])):
--------st = 0
--------for i in xrange(len(Dest)):
------------st += var[i][j]
--------prob += st == 1

----#prob.writeLP("dest.lp")
----prob.solve()

----print "Status:", LpStatus[prob.status]

----for v in prob.variables():
--------if v.varValue >= 1:
------------print v.name[3:6] + ' => ' + v.name[7:10]

----print "objective=", value(prob.objective)

if __name__ == '__main__':
----A = [[1130, 863],
--------[1705, 1283],
--------[1326, 1736],
--------[975, 825],
--------[1286, 807],
--------[909, 1143],
--------[1579, 1608],
--------[1162, 1118],
--------[876, 1573],
--------[1198, 1748],
--------[801, 1134],
--------[956, 1226]]

----B = [[1031, 1206],
--------[1046, 1000],
--------[1803, 1809],
--------[1588, 1821],
--------[1300, 1482],
--------[1939, 1228],
--------[1147, 1703],
--------[1319, 1254],
--------[1300, 1182],
--------[1817, 1269],
--------[1945, 1605],
--------[1349, 1488]]

----dest = caldest(A, B)
----optima(dest)

執行後,得到搬遷方式為:

001 => 009
002 => 010
003 => 003
004 => 002
005 => 006
006 => 001
007 => 011
008 => 008
009 => 007
010 => 004
011 => 005
012 => 012

最小路徑為 4412.0

2007年3月10日 星期六

JavaScript ≠ Java

回應阿西摩的分享誌: JavaScript ≠ Java

題目是對了。javascript的確不等於java,就像java不等於javascript一樣。

但java比javascript高級??這就有問題了。這就像是拿xx比芭樂一樣。

你會拿java applet來作表單,然後在裡面作資料驗證嗎?是有這個可能(需加密的登入表單,如網路郵局的表單),但全世界有99%(這是不精確的形容詞,表示很多而已)的程式師是拿javascript來作。

javascript可以拿作寫桌面程式嗎?現在可能還沒有人拿它直接來作整個桌面程式,只有拿來作桌面程式中的一個小元件,像是檢查使用者輸入指令(javascript sheel),但將來網頁應用程式當道時,又會有多少桌面程式留下來?java跨平台又如何,一堆動態語言(python、perl、ruby、php)都跨平台,連javascript也跨平台(請不要拿Jscript來說,那是微軟自己玩爽的),不只是活在瀏覽器,也可以活在伺服端。

阿西摩只是一個良好的 java 程設師,不是一個良好的 javascript 程設師,因此他的立場不中立。而我不是一個良好的 javascript 程設師,但我卻不妄言 javascript 劣於 java ,所以這應是包含態度的問題。

Use Djange Project Step by Step

當我為這個主題寫第二篇文章時,發現這類型的文章並不適合用 blog 形式展現,文章與文章之間鍵結能力太差了,而且要寫的豐富、深入有時候還需要過客的協助。

所以我把整篇文章都丟到 Trac 系統( http://ptrac.hoamon.info/wiki/UseDjango ),TOC:

Use Djange Project Step by Step
  1. 安裝Django
  2. 使用models建立資料表
  3. 建立 admin 頁面
  4. ……
本來只是想拿 Trac 系統練習多人的軟體專案管理,但用來作自己的文章/手冊管理也不錯喔~

2007年3月8日 星期四

缺失報告及缺失編號的關係

課堂上,提到了一個工程案承辦人員時常面對的困擾:

當工程案被查核、督導後,就會有查核、督導委員的意見,這些意見有的簡短、有的複雜,所以承辮人員把這些意見分門別類到工程會制定的缺失編號時,往往傷透了腦筋,如何正確地快速地為這些意見作分類就是一個值得探討的問題。

初步想法是:
反轉一般搜尋的觀念,我用報告內容來找關鍵字。也就是說已經擁有一堆關鍵詞的集合,用這個關鍵詞集合來搜尋報告內容,然後依關連性高至低排列,讓使用者點選這篇文章應分類到那個集合。

系統並由此得到一次回饋,強化某報告與某集合的關連性。

須作到的工作有:
  1. 報告的中文斷詞
  2. 分析某分類的關鍵詞集合為何
  3. 關連的基本資料庫

自然數中的特定自然數集合?

大家似乎對數學問題的程式求解非常有興趣。我這邊再提供一個數學問題,這本來是我的碩士論文要作的題目(其中的一個部份)。

1條18公分長的竹筷,如果要分成10、7、2、3公分的話,且剩餘的長度不可大於等於2公分,這樣有那幾種分法?

程式要能寫到任意長度的竹筷可被任意個數的自然數切割。

我的程式目前只有 Perl 版的,過幾天改成 Python 版的,再 po 。

2007年3月5日 星期一

Python: pydoc ?!?

pydoc? 這是什麼東西~~怎麼學 Python 半年了,今天才在 Trac-Hacks 看到有這個東西。

天呀!!用 Perl 時,我們是離不開 perldoc ,不管是無聊,還是忘了函式用法,看 perldoc 總是第一件事。但我在學 Python 時,查類別方法時,都是用 dir() ,要不就上網查答案,從來沒想過 Python 也有類似 perldoc 的工具。

天呀!!我看的 Python 書,怎麼沒人提這點呢??真令我感到不解,一定是我跳著看,就這麼地跳過去了。

而且 pydoc 還有一個貼心的設計,只要你打下列這個指令

# pydoc -p iii

iii表1個大於1024,小於65535的正整數。你就可以用瀏覽器在 http://127.0.0.1:iii/ 觀看整個 pydoc 的內容。

真棒~~

Google Desktop

發現什麼不一樣了嗎?

Google單字下的「桌面」代表的是這個頁面不是從 www.google.com 來的,而是灌了 Google Desktop 程式。這個頁面的來源其實是 http://127.0.0.1:4664/ ,完完全全的一個安裝在本地端的網頁應用程式。

這個應用程式的功能,主要是讓你尋找本機上的檔案,不只是找找檔名而已,檔案中的內容以及你在 Gmail 上的信件也可以搜索,而且重點是,
它用起來的速度就像你找網頁一樣快。

Google 真棒!!

2007年3月3日 星期六

3X5 = 2X8 ??



上圖合理嗎?

答案請用滑鼠選取下面的空白處:

當然是不合理的。因為綠三角的斜率為 2/5 ,紅三角為 3/8 ,兩個合在一起怎麼會是1個直角三角形呢。

答案請用滑鼠選取上面的空白處。

微軟徵才試題

永源拿了兩個不同數字...
這兩個數字分別大於 1 ,也分別小於 50

永源只把這兩個數字的乘積告訴了亞譚 ...
永源再只把這兩個數字的和告訴了明歆 ...
永源問, 這兩個數字是什麼 ?

以下是亞譚和明歆的對話... (小強, 小毛, 小燕在旁坐陪)
亞譚: 我不知道這兩個數字是什麼!
明歆: 但我也還是不知道這兩個數字是什麼!
亞譚: 喔!那我知道那兩個數字是什麼了 !
明歆: 喔!那我也知道那兩個數字是什麼了 !
突然間 ....聰明的三位陪客同時也說: 我們也知道那兩個數字是什麼了 !
聰明的你, 告訴我....那兩個數字是什麼 ?

原文應是英文,翻成中文後,求解卻有多組,所以上文已有作過部份修改。

之前聽到這個題目時,是用質數的概念來解的,這方法不對。今天聽了老師的講法,才知道應是用集合的方式。

求解的邏輯如下:

找出兩個數字「積」的集合,把只出現1次的全部刪除,針對剩下數字對,把「和」的集合中,只出現1次的刪除。

這樣留下來的數字對只剩下638對。然後我們針對638對所產生的「積」,去找出對應數字對的「和」出現有幾次。如:
1344的積有兩個數字對(28,48)及(32,42),所以「和」為76及74,再去對應638對中的「和」是76的有幾次,74的有幾次。最後我們得到1344的「和」次數集合為(2,3)。

這一定不是我們要的答案,因為亞潭知道但明韶不知道的原因,在於只能有一個次數大於2的「和」次數集合,而上述的1344共有2個大於2的集合。

所以我們所要找尋的「和」次數集合應為(2,1,1,1,1)、(3,1,1,1)或是(6,1)之類的。

程式邏輯如下:

利用 dictionary(hash) 的特性,把「積」集合放在 times 變數,key為積值,value為對應的數字對陣列;「和」集合放在 plus 變數,key為和值,value為對應的數字對陣列。

刪完了只出現1次的數字對後,把剩下的「積」集合放到 s_times 變數;「和」集合放到 s_plus 變數中。

最後一個迴圈,則是把剩下的「積」集合中,所對應數字對的「和」次數集合(放到 a 陣列)找出來,並找出其次數只有1個大於2的 a 陣列,而 a陣列中惟一大於2的「和」其數字對即是解答。

Python 程式碼:

#!/usr/bin/python

(times, plus) = ({}, {})
for i in xrange(2, 50):
----for j in xrange(i + 1, 50):
--------if(times.has_key(i * j)):
------------times[i*j].append((i, j))
--------else:
------------times[i*j] = [(i, j)]
--------if(plus.has_key(i + j)):
------------plus[i+j].append((i, j))
--------else:
------------plus[i+j] = [(i, j)]
--------
(s_times, s_plus) = ({}, {})
for (t_k, t_v) in times.items():
----if(len(t_v) >= 2):
--------for (i, j) in t_v:
------------if(len(plus[i+j]) >= 2):
----------------if(s_times.has_key(i * j)):
--------------------s_times[i*j].append((i, j))
----------------else:
--------------------s_times[i*j] = [(i, j)]
----------------if(s_plus.has_key(i + j)):
--------------------s_plus[i+j].append((i, j))
----------------else:
--------------------s_plus[i+j] = [(i, j)]

for (t_k , t_v) in s_times.items():
----(a, b) = ([], 0)
----for (t_i, t_j) in t_v:
--------a.append(len(s_plus[t_i+t_j]))
----for a_i in a:
--------if(a_i >= 2): b += 1
----if(b == 1): print str(t_i) + ', ' + str(t_j)

後記:

老師講解這題的時候,是用 Matlab 程式求解的。我在課堂上,嘗試用 Python 求解,怎麼想都想不出來,直到回家路上,才發現看了 Matlab 程式後,一直把矩陣觀念放在腦中,而基本的 hash 原理全忘了。我還是得一次只作一件事吧!

2007年3月2日 星期五

Python: 持續讚嘆中

我幾天都在 Python 的領域中翻滾,看了許多 TracDjango 的文件,覺得 Python 開發模式實在是太棒了。這對過去常用 PHP 的人來說,是一種新鮮的經驗。

感到最大的不同點是:
  1. 自己帶 web server裝
    • Trac 或 Django 的程式時,它們會自己帶一個 http deamon(lighthttpd) ,所以程式裝完,不太需要設定,就可以跑了。
  2. 程式是裝在系統中,而不是 www 資料夾
    • 並不像 PHP 的專案,要把所有的程式放在某個地方,然後設定 apache 的 DocumentRoot 。這些 Python 程式就像是一個元件或函式庫是放在系統用的資料夾中,也就是當你要寫別的專案時,直接在程式碼中 import 進來。而不是 require('特定位址的 php 程式')
因為第2點的特性,所以軟體工程師在開發 web 專案時,必需將程式以 class 的方式存在,所以專案的可用性也就提高了。

Python 真是好東西呀!
Related Posts Plugin for WordPress, Blogger...