用virtualenv,除了可以建出一個開發環境之外,也不會因為distribution不支援而扼腕,然後也可以輕易地安裝、搜索跟反安裝。另外一個好處就是可以輕易的把整份環境給凍結起來。用 pip freeze > requirement_file 可以把開發環境中有安裝的package都列出來,然後再用 pip install -r requirement_file 就可以裝回去。
dateutil.parser解析日期時間字串出現”iter() returned non-iterator of type ‘_timelex'”
之前用python-dateutil的parse在解析字串是沒問題的,結果今天用的時候,卻出現 “iter() returned non-iterator of type ‘_timelex'” 的錯誤,仔細看過,發現之前用的是1.5,而目前用的卻是2.0。上官方網站去看,發現1.5是for Python2,而2.0是for Python3,為什麼不能相容呢?一時之間也無法解決,乾脆就降級用回1.5了,還好用virtualenv跟pip,還蠻簡單的,就先 pip uninstall python-dateutil 再 pip install python-dateutil==1.5 就行了。
電影流水帳(2012/1/20~2012/1/26)
- Rise of The Planet of The Apes(IMDB, Wikipedia),中譯:猩球崛起。很好看的電影,是多年前決戰猩球的前傳,描述為什麼地球會演變成猩猩變成高等人類的星球。其實就是Will為了解決父親老人癡呆症的問題,而去研發出一種新的病毒作為新藥,經過實驗,猩猩的智力的確有驚人的成長。後來,因為某些變故,使實驗室主持人下令將這批猩猩銷毀,但是有一隻小猩猩,Robert不忍心下手,就交給了Will。小猩猩Caesar繼承了媽媽的血,也有高等智慧。經過數年之後,小猩猩越發聰明了,而Will偷偷把還沒人體試驗的藥物用在自己的父親身上,也得到了很好的成效。但是,隨著時間過去,Will發現父親的免疫系統已經開始可以抵抗病毒,老人癡呆症也愈來愈嚴重。Will決定冒險開發新的藥物,以解決父親的病症,於是他告訴實驗室主持人說自己已經拿父親試驗過,希望可以開發新的藥物。實驗室主持人在知道藥物有效之後,就決定繼續進行研發計劃。就在藥物快要完成的時候,出現了實驗室意外,Robert不小心吸入了病毒。而Will的父親老人癡呆症也越發嚴重,讓猩猩Caesar為了救他而讓鄰居嚇到,並因此被關到動物管制中心。Caesar在管制中心裡並不愉快,很想要離開,但是受限於法律,Will沒辦法。過了一段時間,聰明的Caesar偷到了小刀,並且收買了中心裡最強壯的猩猩,對抗欺負他的猩猩,然後成為中心裡領袖的角色,為了讓同伴更加聰明,他去Will的實驗室偷到新藥物給猩猩,讓所有的猩猩變得非常聰明。某天,這些猩猩就發難逃了出去,引起軒然大波,並逃到了舊金山北邊的Redwood。而Robert去Will家裡找不到Will的情況下,讓Will的鄰居感染了病毒,而Will的鄰居剛好又是機長,要飛到全世界,於是病毒擴散到整個世界,剛好這個時候又有太空人飛到太空去。飾演Caesar的角色其實是Andy Serkis,之前曾經飾演過Gollum,也難怪在講猩猩的時候,讓人真的以為他是人。
- Attack of the 50 Foot Woman(IMDB, Wikipedia),中譯:巨型女的襲擊。自己笨,被簡介跟海報騙了,特技效果不突出(1993年的電影)、故事普普,而且還看了國語配音的,才看了沒幾分鐘,就沒耐心地開始亂跳著看完。主角Nancy被丈夫背叛,被父親操控,整個很不爽。有一天被飛碟的光照到,然後就變大了。變大以後,心智也慢慢改變,所以後來就愈來愈不爽,就開始發飆。後面被直昇機打到,就昏倒,被飛碟救走,被救走的時候,她花心的老公也被帶走,片尾是3個巨型女在飛碟裏面看3個花心男在那邊吵架的畫面。
參考資料:
電影流水帳(2012/1/9~2012/1/19)
- The adjustment Bureau(IMDB, Wikipedia),中譯:命運規劃局。這應該算是一部頗揪心的愛情片。男主角David參加眾議員競選,投票前被爆了醜聞,結果沒上。要發表落選演說時,遇到女主角Elise,一見鍾情又一見傾心,還沒來的及留下電話,就分開了,David因此發表了一篇不凡的落選演說。後來,David要上班時,竟然在公車上巧遇Elise,兩人超happy,互留了電話。David到了辦公室,發現好奇怪,一堆人都被停住了,他遇到了The adjustment team正在調整眾人的思維,他就拼命逃,可是還是沒能逃過The adjustment team的魔掌。他被警告說,不可以洩漏我們的存在,在Elise的電話號碼被撕掉以後,David被放走。之後,The adjustment team裡的Thompson出來偷偷告訴David一些事情,David只好放棄。隔了3年之後,David上班途中竟然再次看到Elise,重新邂逅,The adjustment team出來強制干預,並要脅David,跟Elise分開的話,你會變成總統,Elise會變成知名舞者,如果不從,Elise的腿可能就不只是扭傷而已。於是David為了Elise好,就把Elise丟在醫院,忍痛走了。又隔了好一陣子,David在報上看到Elise要結婚了,他真的不能忍受,而Elise也很猶豫,透過Thompson的幫助下,David成功的阻婚,並在The adjustment team的阻撓下,逃到了某大樓上。最後的結局是,The adjustment team其實是天使,而命運則是由上帝寫的,因為上帝很感動,就改寫了他們兩人的命運,然後就沒了。
- Detroit Metal City(IMDB, Wikipedia),中譯:重金搖滾雙面人。根岸熱愛音樂,在大學畢業後,卻誤進了重金屬搖滾的唱片公司,組成了Detroit Metal City,非常的紅。某天,他遇到了大學時代心儀的舊識由利,開心的聊了起來。之後發生了一連串的誤會,並且又不小心成了日本最紅的樂團,成了美國重金屬搖滾樂團的目標。就在這個時候,他被由利很深的誤會,非常灰心,回去老家。在老家,他扮為克勞薩二世,教訓了弟弟,並且,也接受母親的開導而想開,決定回到東京接受挑戰。最後就以戰勝美國重金屬樂團而告終。裏面蠻多好笑的片斷,像是社長弄息煙的方式跟克勞薩二世在老家開割草車等等,蠻好看的片。
- Pirates of the Caribbean: On Stranger Tides(IMDB, Wikipedia),中譯:神鬼奇航-幽靈海。還算可以的續集片,沒什麼特別的亮點。就一堆人陰錯陽差去找不老泉,有人是為了報仇,有人是為了生命,有人是去看熱鬧,有人是去搞破壞。Sparrow跟Gibbs有地圖,是知道路的人,主要是去看熱鬧順便把黑珍珠號拿回來的,Barbossa去報Black beard的仇,Black beard是為了生命,他快死了,豈知後來因此而死,西班牙國王去搞破壞,他不允許有東西超越上帝賜與人的生命。最後就是泉水被西班牙破壞,Barbossa得償所願,Black beard掛掉,Angelica被放逐,Sparrow跟Gibbs拿到黑珍珠號跟其他一堆船,看起來是還會有續集的樣子。
ping in Android(續)
後來發現裏面有包ping這指令,而且有設置setgid權限,那麼應該是可以執行。只是試了之後,卻不行,然後我就以為不行。之後不死心,把stderr接出來看,才知道我下錯指令,於是修正以後,就可以了。
[java]
final class Helper {
private final String TAG=”Helper”;
private void pingInExec(String host) {
Runtime runtime = Runtime.getRuntime();
String command = String.format(“/system/bin/ping -c 2 %s”, host);
Process proc;
try {
proc = runtime.exec( command );
BufferedReader in = new BufferedReader(new InputStreamReader(proc.getInputStream()));
BufferedReader err = new BufferedReader(new InputStreamReader(proc.getErrorStream()));
String inputLine;
while ((inputLine = in.readLine()) != null) {
Log.d(TAG, inputLine );
}
in.close();
while ((inputLine = err.readLine()) != null) {
Log.e(TAG, inputLine );
}
err.close();
proc.waitFor();
int exit = proc.exitValue();
Log.d(TAG, String.format(“exitcode=%d”, exit) );
if (exit == 0) { // normal exit
Log.d(TAG, “RESPONSE_OK”);
} else { // abnormal exit, so decide that the server is not reachable
Log.d(TAG, “RESPONSE_TIMEOUT” );
}
} catch (IOException e) {
Log.e( TAG, e.getMessage() );
} catch (InterruptedException e) {
Log.e( TAG, e.getMessage() );
}
}
}
[/java]
ping in Android
上網找了一下,一般對於ping的建議是直接利用java內建的InetAddress.isReachable()來做,實際上在ping內部網路的伺服器時,是沒問題的,但是如果要ping位於外部網路的伺服器時,就會失敗而回傳False。
Android內部的實作是在libcore/luni/src/main/java/java/net/InetAddress.java裡,這裡就很簡單的建立socket,然後試著連到指定位址的port 7,如果可以連,或者是伺服器明確地拒絕,就視為伺服器存在,可以連線。這就解釋了為什麼無法ping位於外部網路的伺服器,因為ISP為了安全或是其他考量,而不允許。我分別以python與java寫了與Android實作相似的程式去實驗,的確都不行。
[python]
import sys
import socket
if len(sys.argv)<2:
print( “Need at least 1 parameters.” )
print( “Usage: {0} host”.format( sys.argv[0] ) )
sys.exit(-1)
r = False
try:
s = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
s.settimeout(5)
s.connect( (sys.argv[1], 7) )
r = True
except socket.error, ex:
if ex.errno==111:
r = True
else:
print( ex )
if r:
print( “{0} is reachable.”.format( sys.argv[1] ) )
else:
print( “{0} is NOT reachable.”.format( sys.argv[1] ) )
[/python]
[java]
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.io.IOException;
class Ping {
public static void main(String[] args) {
InetAddress in;
try {
in = InetAddress.getByName(args[0]);
boolean result = in.isReachable(5000);
if (result) {
System.out.println(“Response OK”);
}
else {
System.out.println(“Response fail”);
}
} catch (UnknownHostException e) {
System.out.println(e.getMessage());
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
}
[/java]
Java裡只能建立 stream(TCP) 或 dgram(UDP) 的socket,那麼只能用JNI,用C寫ping了,但經過實驗結果,發現會因為權限的關係而無法建立socket,原來要建立raw與IPPROTO_ICMP的socket,需要root權限。一般linux裡,非root使用者可以使用ping,是因為ping加上了setuid權限,才能使用。在Android裡,要不就是建立service,要不就是設法為ping加上setuid,否則是都無法使用的。
Get IP Address in Android
這篇Get the ip address of your device on Android Development其實就講的很清楚了,就是用NetworkInterface.getNetworkInterfaces()去取得所有網路介面,然後再用網路介面的getInetAddresses()去看該網路卡上的所有IP位址,然後把Loopback位址排除掉,就可以取得了。該開的權限有android.permission.INTERNET與android.permission.ACCESS_WIFI_STATE。
我工作上的需求,是要拿到3G那邊的IP,經過實驗,發現在WiFi開啟的情況下,只會拿到WiFi網路介面的IP位址,而非3G網路介面的。如果把WiFi網路介面關閉,就可以拿到3G網路介面的IP。我以為是程式邏輯的關係,可是在確認過NetworkInterface.getNetworkInterfaces()傳回的網路介面數量以後,發現都是取得兩個網路介面,而非我預期的三個。好,那我不使用NetworkInterface.getNetworkInterfaces()改用NetworkInterface.getForName()去取的話,在WiFi開啟的情況下,取得的結果會是null,也就是說該網路介面被關掉了。
直接去看底層,在 mydroid/libcore 下NetworkInterface的JNI函式,那邊是使用netlink去跟kernel問所有的網路介面,然後解析之後傳回。那麼底層應該是沒有問題,看來是中間層為了能取得較快的網路速度,而自動把3G網路介面給關閉了。看來也只能在程式執行前,先把WiFi給關閉,才能取得3G網路介面的IP位址了。
參考資料:
[ExcelVBA]刪掉所有sheet,只留下指定的sheet
上星期的某天花了一個小時在寫這個Script來幫我刪sheet,程式邏輯很簡單,很快就搞定了,只是另存新檔,打開以後,卻什麼東西都沒看到。存為 .csv 的話,的確是有資料,那就奇怪了,百思不得其解。一放就又放了一個星期,這次終於解開秘密了。另存新檔以後,不知道為什麼,打開以後視窗會被隱藏,所以什麼都看不到。只要取消隱藏視窗就可以看到了。程式的話,就是要這樣寫: Application.Windows(1).Visible=True,下面就是整個程式:
電影流水帳(2012/1/1~2012/1/8)
轉眼又是新的一年。
- Cowboys & Aliens(IMDB, Wikipedia),中譯:星際飆客。中文翻譯還蠻能唬人的,算了。這是一部西部片,只是對抗的人變成了外星人。故事很簡單,男主角一開始是喪失記憶的,手上帶了一個莫名其妙的手環,然後他到了小鎮。小鎮旋即被外星人襲擊,一堆人被擄走要解剖用。然後男主角就跟小鎮上最硬的人組隊去救人,在途中,男主角慢慢想起以前的事情,也跟女主角等人慢慢熟起來。然後終於找到外星人的飛船,就決定先把外星人引出來打,男主角跟女主角趁機進去救人。外面真的幾乎是一場一面倒的戰役,那個時代的槍沒打到要害的話,基本上是打不死人的,就子彈卡在肌肉裡這樣,所以外星人根本是所向披靡。不過在電影的加持之下,還是幹掉了不少外星人。題外話,其實外星人的設定不是很合理,為什麼身體還會打開,把要害攤給別人看還會伸出另外兩隻手呢?不過反正是外星人,我想我就別在意了。在硬撐了許久之後,終於把人救了出來,女主角其實也是外星人,是要來報仇的外星人,所以就拿了男主角的手環下來,轉成炸彈,進去核心。男主角趁機會趕緊逃了出來,女主角最後就把外星人的船炸掉,就這樣。大致上不難看啦,最可惜的一幕是女主角死而復生的那一段,她從火裡走出來,衣服都被燒光光,我蠻想加入那些圍觀的人說,想知道為什麼他們那麼驚訝。(你劃錯重點了好嗎?驚訝是因為她死了又再復活,不是沒穿衣服的問題!!)
- Iron Man 2(IMDB, Wikipedia),中譯:鋼鐵人2。Tony因為控制不住palladium的關係,生命不長久了,所以就開始亂搞,並且讓Pepper當CEO。在西班牙遇到他老爸朋友的兒子Ivan Vanko,一陣亂打讓鋼鐵人跟Starks工業的名聲大為降低,讓對手Hammers工業趁機而入。一整個low到谷底,一具鋼鐵人又被美國國防部拿走的情況下,神盾局的人跑出來跟他說palladium不是最好的元素,給他打了抑制Palladium的藥物並給了他他老爸的遺物,說有更好的元素可以用,他摸索一陣子之後,找到了製造新元素的方法,然後噹噹噹,新的core誕生了,arc reactor更為強大。Ivan被Hammers吸收以後,幫他們研發,但不聽他們的話,而是搞自己的,所以在Expo時,他遙控一堆機器人跟Iron Man打,這堆機器人真的很酷啊,但Iron Man跟他的朋友聯手把這堆機器人幹掉,Ivan大魔王現身,最後以解決掉大魔王告終。這一集Pepper的戲份不多,好可惜,我很喜歡她說。然後飾演Natalie的Scarlett Johansson是一個亮點,她的武術動作真的好酷,然後她真的很適合演這種酷酷的角色,The Spirit裡是這樣(有多一點搞笑),這裡也是這樣。
http://en.wikipedia.org/wiki/Whiplash_(comics)#Film
skydrive+FUSE的read
這幾天弄skydrive+fuse的時候,一直在想,這到底適不適合用FUSE來實作?
- 以網路程式來說,讀取的時候,要可以告訴伺服器端,客戶端要下載那一段,要下載多少,以HTTP來說,這可以用Range這個header來達成,只要在發request的時候,加上Range header就可以指定。那麼skydrive伺服器端有支援續傳嗎?這個我還沒去確定。
- 那麼FUSE的read裡可以使用續傳嗎?在read裡會指定要讀取多少,從哪裡開始讀取,看來是可以使用續傳,可是使用續傳的話,就要考慮一下客戶端的情況,一般在做這種read的時候,是使用一個回圈,然後一次只讀取一部份到緩衝區裡,並不是一次讀完,因此,只讀取一部份的結果,等於會送出許多次的request給伺服器端。
- 可以不要送出許多次的request嗎?這樣網路會折返很多次。一次下載完,先放到硬碟的話,就要面對同步的問題。首先第一次read時,就要可以傳回一部份值,並且要把這個下載的動作放到thread去執行,繼續下載,並放到某個暫存的地方,直到下載完成。那接下來第二次要read時,再去讀取已經下載的部份並傳回。這樣會少掉比較多的request,效率也會比較高一點。可是thread在寫的時候,另外一個thread可以去讀取正在寫入的檔案嗎?會不會有什麼奇怪的事情發生呢?這個是需要實驗的地方。
- 延續前面的討論,現在已經放到暫存的地方,存取會快很多,可是該怎麼知道伺服器端的檔案被更改了?這應該可以在一開始要read的時候,去判斷檔案大小跟屬性來判斷是不是要重新下載。另外也要考慮到伺服器端檔案被頻繁更動的情況。
- 既然會放到暫存的地方的話,是不是乾脆像dropbox那樣用sync的方式來做會比較好?