顯示具有 programming 標籤的文章。 顯示所有文章
顯示具有 programming 標籤的文章。 顯示所有文章

星期四, 12月 11, 2008

[tips] 針對特定model改變django ORM預設delete()行為的方法

Django ORM裡的預設delete行為是去模擬ON DELETE CASCADE, 主要是為了保證資料的一致性, 但是雖然在自帶的admin介面裡會提示是否要刪除其他相關聯的資料, 不過仍然可能會對某些需求帶來一些困擾, 而且到目前為止並沒有一個標準的方法來更改這個機制, 這邊我提供一個簡單的方法將model的ON DELETE CASCADE行為改為RESTRICT, 就是在需要不同機制的model裡去override orm原本的delete行為 :

 
def delete(self):
s = CollectedObjects()
self._collect_sub_objects(s)
if len(s.items()) == 1:
super(self.__class__, self).delete()
else:
pass



這可確保當沒有任何關聯物件時才會刪除, 否則只會安靜的pass,
this hack probably need django 1.0+.

星期二, 4月 15, 2008

[tips] using pyrex to do the argv[0] trick in linux using python.

A trick to rename python process in output of 'top' and 'ps'.


set_argv.c:

#include
#include
#include

int get_argc(){
int argc;
char **argv;
Py_GetArgcArgv(&argc, &argv);
return argc;
}

void set_argv_via_number(int num,char *str){
int argc;
char **argv;
Py_GetArgcArgv(&argc, &argv);
strncpy(argv[num], str , strlen(str));
memset(&argv[num][strlen(str)], '\0', strlen(&argv[num][strlen(str)]));
}


set_processname.pyx:

#Warning: this module is not safe and may involve some dirty hacks.
import sys,dl,glob
cdef extern int get_argc()
cdef extern void set_argv_via_number(int num,char *buf)
def set_argv0(thename):
set_argv_via_number(0,thename)

def set_argv(thename):
argc = get_argc()
print argc
for i in xrange(argc+1):
if i==0:
set_argv0(thename)
else:
pass
def set_name(thename):
if sys.platform == 'linux2':
# Set process name. Only works on Linux >= 2.1.57.
try:
libc_loc = glob.glob("/lib/libc.so*")[0]
libc = dl.open(libc_loc)
libc.call('prctl', 15, thename, 0, 0, 0) # 15 is PR_SET_NAME
except:
pass

def set_processname(thename):
space_padding_num = len(sys.argv[0])-len(thename)
if space_padding_num < 0:
#thename is longer than original name
newname = thename[:len(sys.argv[0])]
else:
#thename is shorter. add padding.
newname = thename + " " * space_padding_num

set_name(newname)
set_argv(newname)

compile.sh:
#!/bin/sh
CC=mipsel-linux-gcc

pyrexc set_processname.pyx
$CC -c -fPIC -I/usr/include/python2.5/ set_argv.c
$CC -c -fPIC -I/usr/include/python2.5/ set_processname.c
$CC -shared set_argv.o set_processname.o -o set_processname.so

[tips] building psyco on non-x86 platform. (ie. linux mips little endian)

The trick is to build psyco in ivm mode. The mode slower than the native mode(ivm mode involves a prolog generated-vm, you guess), however it's the only way to compile psyco on non-x86 system. And cross-compiling with distutils is not a trivial stuff, so I just compile it directly.


mipsel-linux-gcc -pthread -fno-strict-aliasing -DNDEBUG -fPIC -DALL_STATIC=1 -Ic/ivm -I/usr/include/python2.5 -c c/psyco.c -o build/temp.linux-mipsel-2.5/c/psyco.o
mipsel-linux-gcc -pthread -fno-strict-aliasing -DNDEBUG -fPIC -DALL_STATIC=1 -Ic/ivm -I/usr/include/python2.5 -c c/platform.c -o build/temp.linux-mipsel-2.5/c/platform.o
mipsel-linux-gcc -pthread -shared build/temp.linux-i686-2.5/c/psyco.o build/temp.linux-mipsel-2.5/c/platform.o -L/usr/lib -lpython2.5 -o build/lib.linux-i686-2.5/psyco/_psyco.so


This generates the C-module extension, and just copy all of py files to correct path and enjoy psyco speed-up! (well, not quite a case for me. It just use way too much memory on our embedded system. But I think maybe it'll useful in other project.)

ps: I should mentioned that I'm doing this on a uclibc linux system.

[tips] if as a pure function in python

http://okmij.org/ftp/Scheme/if-function.txt

here is a trick that we could rewrite a customized not-a-special-form IF in python.


iftrick.py:

#!/usr/bin/env python
def func_true():
print "true!"

def func_false():
print "false!"

def my_if(my_cond,then_func,else_func):
eval((then_func, else_func)[not my_cond].func_code,vars())

condition = True

my_if(condition,func_true,func_false)

condition = False

my_if(condition,func_true,func_false)

===
#python iftrick.py
true!
false!

星期一, 1月 07, 2008

Python: programming language of 2007!

January Headline: TIOBE declares Python as programming language of 2007!

"""
Python has been declared as programming language of 2007. It was a close finish, but in the end Python appeared to have the largest increase in ratings in one year time (2.04%). There is no clear reason why Python made this huge jump in 2007. Last month Python surpassed Perl for the first time in history, which is an indication that Python has become the "de facto" glue language at system level. It is especially beloved by system administrators and build managers. Chances are high that Python's star will rise further in 2008, thanks to the upcoming release of Python 3.
"""

well, the reason is so obvious to me...it's all about gravity thingy ;)

星期五, 9月 07, 2007

[link] A Taste of Haskell 觀後小感

Part I
Part II
Slide

這兩部影片是在OSCON2007裡Simon Peyton-Jones的Haskell演講, 其實已經隔了一段時間, 今天晚上才一時興起去看,

因為知道是Microsoft Research裡的Haskell創造者之一,
原本是預期一個長得鬍鬚長長的老頭 然後開始講一些誰都聽不懂的玄學...
不然應該至少要長得像星際大戰的尤達吧~~

結果看了影片之後發現根本就大錯特錯... 大師不僅可以把玄學講成簡單的道理,
長得還比較像歐比王魁剛金...
連我都似乎開始有點聽懂了 @@ (雖然說這肯定是大師的催眠術)

Haskell最大的賣點不僅在於他是一個純粹的functional programming language,
更重要的是Haskell還帶有非常多在其他語言看不到的高等特性,包括惰性(laziness),型態類別(type classes), monads等等, 而這些特性將有可能會強烈的影響到我們下一個世代的程式設計語言.
也因此在諸多語言裡面也慢慢可以看到Haskell的色彩, 包括Simon Peyton-Jones所提到的C# 3.0, (LINQ據說是受到monads的直接影響), 還有python2之後的list comprehension等等都是例子,我覺得這些特性應該會慢慢的從Haskell中被帶出來讓世人所熟知.

(對了 講到python, lambda,map,filter都還在python 3.0a的builtin/keywords裡面,
只有reduce被移到functools裡. 之前map filter說要被降級好像是誤傳?(未查證))

Simon一開始講的是xmonad, 主要是一個haskell寫的
window manager, 非常的小所以他拿來作說明, 然後就開始講一些functional programming的基礎特性, 我主要注意到他說Haskell的types跟UML一樣是用來表示High level design, 這倒很有意思, 我是個python user/advocators我會喜歡duck typing跟lisp這種dynamic types的語言是很自然的, 但是像Haskell這樣的static typing語言不僅有type inference可以減少累贅感, 另外還可以透過compiler檢查高階設計, Data types的construct語法看起來其實也很接近BNF, 倒是讓我覺得static typing也沒有那麼壞了起來.

不過type classes有點複雜, 這是連Simon這種神人都覺得未來仍有發展空間的東西 我並沒有完全跟上, 改天還要再深入研究.然後就開始講到I/O跟scripting, IO的部份, 並不是很直觀, 網路上對於monad的討論也多到暴 所以我也是聽得很霧 另外也提到了Haskell library的現狀(就我以前try過的一些經驗, Haskell的library不算多, Cabel比較像是python的distutils, 可以裝一些3rd party的module, 不過dependency的部份有點麻煩, 似乎現在有人在發展一些工具在處理不過還是沒有很成熟), 這部份其實我目前比較沒有那麼大的興趣, 所以聽得有點散, 其實python就目前實務使用(套件,標準庫...等等)來說還是比Haskell成熟的多,並沒有很急著要學太多實務部份, 但我覺得Haskell是非常具未來性的語言, 所以現在多花點時間了解一些更基礎的特性或許也是對的.

之後開始聽到有關laziness跟first-class control structures, 這很有趣, 如果有學過lisp的話肯定知道lisp有所謂的special form跟macro, 因為lisp是一種語言的語言(meta language), 可以透過macro來無限制的擴展語言, 所以雖然是在1990年代的OOP風潮前就有的語言但卻可以不改變語言的本身特性而發展CLOS這樣的物件系統, 這也是為甚麼lisp之所以吸引人並且長久有穩定支持族群的原因, Haskell的laziness就是讓function跟data constructors不在第一時間就被evaluate, 直到真正需要的時候才去eval, 而這讓Haskell靠著laziness來取代lisp透過macro來支援special form的方法, 只要單純的撰寫函式就可以更動control structure, 這真是非常酷的特點.

最後simon講到Haskell跟其他語言採取完全不同的方法設計, 其他語言主要是一開始先想辦法讓語言有用(Useful)而慢慢的再來加一些限制讓語言更安全(safe), 而Haskell則是採取一開始是Useless(無用處)但是Safe的設計,然後慢慢的讓語言更加具有功能性.


之後simon也講了一些工具跟網站 畢竟這個演講也只是粗淺的導引, 還是有很多深入的內容要多看多玩才會了解 不過之前也看過一些Haskell的介紹跟導引, 他的演講對於個人提高興趣及指點迷津上我倒覺得成效還不錯.

看完演講總算比較有信心覺得這是個正常人可以玩的程式語言了, 知道玩這個語言沒那麼容易變成瘋狂數學家總是安心不少 ;) 不知道為啥突然想起研究所唸過的Kiyoshi Itō這個超神的家伙,記得聽以前的教授說Ito calculus是他的碩士論文發明了之後, 讓我真是想去再生兩個腦袋, 不過還好haskell裡的lambda caluli沒那麼困難, 只要知道\在haskell裡面是代表lambda, 其他只要lisp學好的話搞不好會更欣賞haskell滿直覺的表示法, 型別的理論我比較少接觸看起來還要多摸, 比較困難的是monad, 有時間的話繼續努力玩玩. (話說大師的催眠術果然是無敵的, 看來只要一直想著這很簡單這很簡單終究會變得..感覺..簡單起來 XD)

星期六, 5月 05, 2007

[link] 誰說只有wiki可以這樣搞.....orz

pure html+js ... 越來越有趣了 :P

Terminal

Home

Blog

星期五, 5月 04, 2007

[humor,hotlink] If On a Spring's Night a String ...


#!/usr/bin/env python
class tim:
def __init__(self,tim):self.chen=tim
def __rlshift__(self,chen):return tim(lambda x,z=self,tim=chen:z.chen(tim,x))
def __rshift__(self,tim):return self.chen(tim)
def __call__(self,x,tim):return self.chen(x,tim)
print "0"+hex(((reduce(lambda chen,tim: tim*chen,[int (x,32) for x in "timchen119"])
*4+119<<tim(lambda tim,chen: tim*chen+119)>>((int("119"+str(93828751754616119383408*127*119))
-1190929898972105379252210654550)))-5210475734-119))[2:-1]

I just wrote my worst python script ever.
I believe it's legal. What do you think?

星期二, 5月 01, 2007

[link] Microsoft發表Dynamic Language Runtime (DLR).

我說, 這名字對了!!! ;D

有了Jim Hugunin的加持之後,
Microsoft這次沒有笨到取一個Sxxxxt Language Runtime這種蠢名字,
看來Microsoft這次真的知道他們在作什麼. ;D

來自Jython/Ironpython作者Jim Hugunin的消息, 看來Microsoft吸收了以往對於網路不夠重視的教訓, 這次對於業界的Dynamic Language潮投注了不少心力.

消息節錄重點如下:

"""
We're initially building four languages on top of the DLR - Python, JavaScript (EcmaScript 3.0), Visual Basic and Ruby. We shipped today both Python and JavaScript as part of the Silverlight 1.1alpha1 release today.
"""

所以說DLR 目前已經支持 Python, Javascript,Visual Basic跟Ruby...

!? Python跟Ruby...!?
喔妳沒看錯... Microsoft居然開始注意Python跟Ruby的支援...
這一天終於要來了嗎?...

並且今天釋出的Silverlight 1.1alpha1版已支援python跟Javascript. (Silverlight看起來將會是下一代Microsoft主推的web平台??)

"""
In addition to the Silverlight release, we've also made the full source code for both IronPython and all of the new DLR platform code available on codeplex under the BSD-style Microsoft Permissive License.
"""

BSD-style Microsoft Permissive License !???

BSD style?!沒聽錯吧... 會不會..太opensource了一點? :DD

看來我這文章標題應該改成==> 神奇的Jim Hugunin
,Microsoft的自由軟體跟Python/Dynamic Language推手... XD

雖然我常常沒事虧一下MS,
不過這次還是得替Jim Hugunin跟Microsoft鼓鼓掌...
在MS裡搞自由軟體... 讚啊...

星期二, 4月 03, 2007

pypy 1.0 first try

I'm not going to explain too much pypy, I'll just list my instructions on C version PyPy 1.0 + jit (pypy-c with jit) build.

* you may need install these first *

apt-get install

gcc libc6-dev make autoconf libgc-dev bzip2
subversion python2.4 python2.4-dev
python-ctypes python-pygame

Note: you don't really need python-pygame if you specify with --text.

Note for debian stable user:

if you're using debian stable, you have to manually install ctypes.

python2.4-ctypes is 0.9.5-1 in debian stable,

pypy need version 0.9.9.6 or later:

wget http://nchc.dl.sourceforge.net/sourceforge/ctypes/ctypes-1.0.1.tar.gz

tar zxvf ctypes-1.0.1.tar.gz

cd ctypes-1.0.1

python2.4 setup.py install

* how to translate pypy to c-version pypy with jit *


WARNING: YOU AT LEAST NEED a 512MB RAM box...
I'll recommend 1GB RAM box.
since this will generate a 700mb python process
( 704m 693m 5872 R 99.9 78.3 53:14.25 python2.4,
I build this on 3.2GHZCPU+1GB ram debian stable box)
I first translate pypy in a 512MB RAM gentoo box,
after 3 days memory swapping I gave up.

wget http://codespeak.net/download/pypy/pypy-1.0.0.tar.bz2

#or svn co http://codespeak.net/svn/pypy/dist pypy-dist

tar jxvf pypy-1.0.0.tar.bz2

cd pypy-1.0.0/pypy/translator/goal/

python2.4 translate.py --batch --text --jit targetpypystandalone

and wait 2 hours (if you have 1gb ram)

* woot! pypy-c !

let's check this:

pypy:/home/tim/pypy-1.0.0/pypy/translator/goal# ls -lh pypy-c
-rwxr-xr-x 1 root root 9.2M Apr 3 16:22 pypy-c

pypy:/home/tim/pypy-1.0.0/pypy/translator/goal# ldd pypy-c
linux-gate.so.1 => (0xffffe000)
libgc.so.1 => /usr/lib/libgc.so.1 (0x4001e000)
libm.so.6 => /lib/tls/i686/cmov/libm.so.6 (0x4004f000)
libpthread.so.0 => /lib/tls/i686/cmov/libpthread.so.0 (0x40074000)
libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0x40086000)
libdl.so.2 => /lib/tls/i686/cmov/libdl.so.2 (0x401b7000)
/lib/ld-linux.so.2 (0x40000000)

* The benchmark part

1. startup time is great

pypy:/home/tim/pypy-1.0.0/pypy/translator/goal# time ./pypy-c -c "print 'hello world!' "
hello world!

real 0m0.006s
user 0m0.003s
sys 0m0.003s

pypy:/home/tim/pypy-1.0.0/pypy/translator/goal# time python -c "print 'hello world!' "
hello world!

real 0m0.009s
user 0m0.005s
sys 0m0.005s

2. jit speed seems promising.

pypy:/home/tim/pypy-1.0.0/pypy/translator/goal# time ./pypy-c demo/jit/f1.py > /dev/null 2>&1

real 0m0.449s
user 0m0.442s
sys 0m0.007s

pypy:/home/tim/pypy-1.0.0/pypy/translator/goal# time python demo/jit/f1.py > /dev/null

real 0m5.347s
user 0m5.343s
sys 0m0.004s

however current JIT not faster than psyco.full():

pypy:/home/tim/pypy-1.0.0/pypy/translator/goal# time python demo/jit/f1-psyco.py > /dev/null

real 0m0.048s
user 0m0.046s
sys 0m0.002s

3. it's a bit slow in a real test in this stage.

I took the nbody test in "Computer Language Shootout",

http://shootout.alioth.debian.org/gp4/benchmark.php?test=nbody&lang=python&id=0

pypy:/home/tim/pypy-1.0.0/pypy/translator/goal# time python nbody.py 20000
-0.169075164
-0.169089263

real 0m1.729s
user 0m1.724s
sys 0m0.005s

pypy:/home/tim/pypy-1.0.0/pypy/translator/goal# time ./pypy-c nbody.py 20000
-0.169075164
-0.169089263

real 0m13.542s
user 0m13.539s
sys 0m0.003s

pypy-c without jit almost 8 times slower :(

and, with the current 1.0 alpha stage JIT, the performance isn't any better.
(since nbody.py use lots of floating arithmetic)

I add these in nbody.py:

import pypyjit
pypyjit.enable(advance.func_code)
pypyjit.enable(energy.func_code)
pypyjit.enable(offset_momentum.func_code)

pypy:/home/tim/pypy-1.0.0/pypy/translator/goal# time ./pypy-c nbody.py 20000 > /dev/null 2>&1

real 0m19.550s
user 0m19.531s
sys 0m0.019s

* conclusion:

1. I don't think pypy 1.0 is ready for production. At least not in my project.
So don't try to replace CPython via pypy at this stage.
(but maybe you have a good reason)

2. pypy 1.0 is not faster than CPython at this stage. Actually, much slower.
(JIT looks promising, however it's still in alpha stage.)

3. pypy really need a 2.0 release. (A joe average user branch)
It looks good,
since it wanna try to do something really different,
but not good enough yet.
we need more.

4. my benchmarking is so naive here, so if you don't like it,
you should do it your own self.

5. despite these, good work.
Thanks the effort from pypy team. we really really need more.

星期日, 3月 11, 2007

可憐的Javascript妹妹啊... 我來聲援妳了~~

""" 不要相信任何失去熱情的人跟你說程式語言不重要,
程式語言只是工具... 不要為了程式語言而戰...
那些人都已經失去戰場跟舞台, 早已不在第一線上了...
遺棄舞台的人, 舞台也終將遺棄他."""

-- by 戰の使徒 使徒提姆


網路上的資訊經常錯誤百出,
老實說我已經見怪不怪了,
由於我很懶惰而且還有其他想作的事情要作,
所以通常我都是扮演跳過之後順便恭維兩句:
"您真內行..." 等等無恥獻媚的鄉愿之徒.

不過阿西摩這篇標題跟文章都讓我看起來就像是
""" Javascript鳥腳本語言 才不是 太陽微電子工業語言 aka. Java宇宙大無敵語言"""
可以說統合了一般非javascript工程師對Javascript天大的誤解之集精華大成.
由於這種百年難得一見的落井下石機會實在難得,
所以基於Python傳教士捨己為人路見不平拔刀相助的仁人理念,
不得不好好的落井下石一番.

雖然說我們Python星球跟Ruby Perl幫的仁人善士早已把這篇批鬥的體無完膚,
卻遲遲不見追Javascript妹幫的js仔出來踢館,
基於前人造出井就是要拿來落井下石的偉大抱負,
我發現我還是得站出來為javascript妹辯護兩句.

我們先來看看阿西摩同學怎麼說的, 阿西摩先引用了wikipedia,


JavaScript並非Java
JavaScript是由網景通訊公司(Netscape)最初在它的Navigator 2.0產品上設計並實現的
,原名LiveScript,除了句法上有一些相似之處以及都能夠提供網頁中的可執行內容以外,
JavaScript和Java是完全不相干的。

JavaScript並不簡單
實際上儘管JavaScript是作為一種給非程式設計師提供的腳本語言而不是給程式設計師提供
的程式語言來推廣和宣傳的,但是 JavaScript是一門具有非常豐富特性的程式語言,和其他所有
的語言一樣複雜或者更複雜,你需要對JavaScript有紮實的理解才能用 JavaScript執行比較複雜
的任務。

原文出處: Wikipedia - JavaScript


然後得到了一個精彩的結論: """所以阿西摩要大喊 JavaScript ≠ Java ,更重要的原因是 JavaScript "充其量""不過是"一種 Script language,中文翻譯為[腳本語言]"""

各位, Wikipedia寫了老大的字:

"但是 JavaScript是一門具有非常豐富特性的程式語言,和其他所有的語言一樣複雜或者更複雜,你需要對JavaScript有紮實的理解才能用 JavaScript執行比較複雜的任務。" ,

這麼清楚的解釋,
阿西摩同學卻得到了"充其量"跟"不過是"這種不能算結論的結論.
我不禁苦嘆: "教育",您怎麼了? Wikipedia是這樣引用的嗎?
那我下次引用漢摩拉比法典說Java充其量是巴比倫人不用的語言好了. :P

再來阿西摩同學又引用了Wikipedia,
得到了一個有趣的結論: Java屬於工業編程語言.
這點各大中文部落格一兩個月前都已經戰到出火了,
當然我也不得不順便在此宣布Python是帥哥正妹跟華夏無敵高手才會用的語言.

好了, 看了這麼一堆狗屁的東西,相信大家一定都頭暈了。好吧,使徒提姆現在就用自己的解釋來說 JavaScript ≠ Java ... 我讀起來阿西摩大概就是這麼說的.

好了, 基本的狗屁都過去了, 來看看太陽微電子學派的六大錯誤論點吧:

1. 阿西摩:"""JavaScript 只要有一個網頁跟有支援 JavaScript 的瀏覽器才可以執行."""

喔喔... 是這樣喔...沒看過SpiderMonkey也看過Rhino吧?
Rhino還是用太陽微電子語言寫的呢.

接下來阿西摩同學還說了(至少我讀起來是這樣)
"""只要程式內沒有使用什麼特殊平台的 library ... (跨平台) ... 都不會有太大的問題"""

這句話要好好練習練習, 升官發財就靠這句了.

2. 阿西摩:"""最原始的 JavaScript 能操作跟執行的範圍相當有限,比方說,你如果要讀取本機端的檔案,比就必須搭配 JavaScript extension 還有 ActiveX 之類的附註程式才有可能達稱。而 Java 可以輕鬆的使用 Java 原本的 package 去讀取檔案,更改檔案。"""

拿木瓜比菜瓜... 不如說Java還有咖啡可以喝好了... 照樣造句也可以來一句:
"Java要搭配Java程式庫跟瀏覽器的plugin才能XX OO YY,能操作跟執行的範圍相當有限"

看官, 了解了嗎, 欲加之罪何患無詞? :P

3. 阿西摩:"""而比起 JavaScript,Java語言,有自己的標準,架構,平台,而且複雜度高上太多太多了,所能應用的範圍更是會把 JavaScript 巴到連渣都不剩!"""

是是是... 阿西摩說的好... Javascript渣都不見了... Java還剩很多... (渣?...)

Javascript標準,架構,平台樣樣不缺, 至於語言的特性跟範圍,

Joel Spolsky去年發表了一篇"""Can Your Programming Language Do This?""",裡面的例子就是採用Javascript, 順便又替早就人人喊打的java又多踢了兩腳.

是的, 妳還可以仔細閱讀...

"JavaScript:
The World's Most Misunderstood Programming Language"


The JavaScript knowledge gap

稍微多瞭解一下知識.

不過說到要比複雜度, 不知道Levels of JavaScript Knowledge您是第幾層?

"""I would even go so far as to say that the fact that Java is not hard enough is a feature, not a bug, but it does have this one problem.""" Joel Spolsky這麼說.

但是隱藏在這後面, 最可怕的媚俗誤解並不是上面我提的這些, 
是居然用語言的複雜度來論斷一個語言.
也就是說一個語言只要搞得很複雜然後說自己很嚴謹就突然變的了不起了起來.
當年C++派人士這樣對待Java先鋒們(我是很敬佩這群先鋒的, 至少人家敢挑戰權威)
現在他們的徒子徒孫好的不學又學到這招打壓的威權思想,
不知道該作何感想. 只能說歷史一直重演.
不如所有人都去學機器語言算了. 反正一切都是0跟1嗎. :P

4. 阿西摩:"""JavaScript 是一種非常不嚴謹的腳本語言。在 JavaScript 裡面,變數全部都用 var 宣告,如果你這樣在 Java 裡面寫程式,我跟你保證,Java compiler 會不斷的,一直的給你[舉紅牌]!"""

非常明顯的錯誤加上完全莫名其妙的結論跟推理過程.
阿西摩說: "在 JavaScript 裡面,變數全部都用 var 宣告"...
這完全是錯誤的資訊,
var不是一種變數的宣告,
var是表示這個變數是local variable, 是一種scope的概念.
不論有沒有var都是個變數, var只是一個scope修飾子,
而javascript的variable scoping rule是implicit global scope,
講的這樣囉哩囉唆, 還看起來太專業了所以妳不知道嗎?
喔 那JavaScript 是一種非常不嚴謹的腳本語言到底是怎麼得來的結論?
要戰動態型別嗎? 那我看這篇文章可以自動加個八千行了, 別了吧...XD

阿西摩:"""如果你這樣在 Java 裡面寫程式,我跟你保證,Java compiler 會不斷的,一直的給你[舉紅牌]!"""

喔如果妳在javascript裡寫java樣子的程式, java script debugger也會不斷的給妳舉紅牌 還按到妳手酸為止耶...

嚴謹不是java能規定的. 嚴謹主要還是來自於Programmer的撰寫習慣跟對程式碼的尊重. Period.

5. 阿西摩:"""我可以用 Java 語言,在 Java Server Page (JSP)上動態產生 JavaScript 語言,並且執行,而你想要用 JavaScript 去寫 Java語言!? 嗯,還是不要沒事找自己麻煩的好!"""

降子啊... 我又想照樣造句了耶, Javascript還可以動態產生Javascript呢... 妳如果想用java語言去產生java語言,, 恩... 還是不要沒事找自己麻煩的好...

反正這種句子隨便怎麼造再給個論斷 聽起來都言之成理,

還不過就是市場機制驅使不少人有了一種java的優越感罷了.

錢跟價值突然就等價了起來.

javascript的原罪就在於太簡單就能學,

一堆人隨便剪剪貼貼就以為會了,

加上不長進的公司又沒啥高深的需求,

當然領的錢就少.

不過放心吧,

照ajax被一群工程師惡搞的趨勢來看,

搞不好以後會變的很難又亂七八糟的.

(當然啦 還是會有一股清流的... 不過清流一般來說都只能在山裡隱居 沒辦法成為主流的)

反正就暫時隨便阿西摩說吧, 搞不好哪天就會突然為了錢想學個什麼ajax起來,

到時搞不好javascript又什麼都好了... XD

6. 阿西摩:"""總之,JavaScript ≠ Java 你是要我說多少次才會聽懂啦!"""

我聽懂了... 可是我覺得錯誤百出ㄟ... XD

再來呢, 阿西摩同學又示範了Helloworld這個艱難的程式用兩個語言撰寫之後,

又發現自己的Java專業被人家當作"Javascript"這種"""垃圾"""看待...

各位... 到底是誰得了便宜還賣乖? 寫兩個helloworld就得出了後面這個結論,

"""因為 Java 背後的專業性,應用範圍,
絕對不是 JavaScript 那種 SCRIPT 語言可以比較的!"""

公理自在人心,
妳覺得, 被人以錯誤的理由跟藉口(其實只是不滿Javascript跟Java名字像而已,就像路上遇到一個跟你撞衫的傢伙不爽就砍他兩刀)打了一巴掌又踢了一腳, 是不是不值得生氣?

我充分能理解阿西摩這篇文章那幾十篇留言的心情,
不理解這種心情的人想必是還沒瞭解被他人輕視的感覺的,
想當年, 我也被論文口試的教授說:"為什麼用這種全天下只有妳會的語言(python)
為什麼不用Matlab?"
我也只是乖乖的摸著鼻子而已.
出了社會有時使用Python也常被冷嘲熱諷,
所以為了真正的程式之道忍辱負重還要被踢上兩腳. 其實我已經習慣了.

但是各位, 我為Javascript妹妹抱不平啊.......!!!
(我這個人, 看到正妹就是心地好+憐香惜玉...XD)

不過阿西摩妳也不用氣餒,
阿西摩的文章也沒有說自己的文章是什麼阿西摩十誡,
頂多只是宣導了錯誤的東西罷了,
所以雖然阿西摩的文章錯誤百出,
雖然我講的話向來很直,
但是文章是文章, 人是人,
文章即使再怎麼差勁, 人是會進步的,
俗話說的好, 不打不相識,
相信經過眾人的洗鍊之後, 還是會有所成長的!

希望阿西摩以後能發表值得嘉獎的文章,
這樣我也不用花一兩個小時來打一篇廢話這麼多,又不怎麼中肯
還把我整年戰文的Quota都用完的文章了.

ps: 各位居然能撐到這邊看到這裡的看官,
這篇主要還是屬於麻辣Humor類,
也就是消遣人當娛樂的類型,
看過吳X憲的節目吧?,
如果有人因為我的狗屁廢話生氣上火了那就不好了,
因為我還是會繼續消遣下去的 .

請仔細看我的右下方特別聲明喔, 我是自High派的. XD

ps2:

Javascript妹妹, 我這麼熱情的聲援妳, 請妳愛我吧!! (趁亂告白篇)

阿阿不行不行, 我已經有Python了, 雖然難過, 我們的相遇實在是個錯誤, 還是分手吧... XD

星期六, 3月 10, 2007

你今天FizzBuzz了嗎?

FizzBuzz的問題由來已久, 基本上"應該"很簡單,
而且你"應該"不需要知道這問題還有個名字叫FizzBuzz:

Write a program that prints the numbers from 1 to 100. But for multiples of three print “Fizz” instead of the number and for the multiples of five print “Buzz”. For numbers which are multiples of both three and five print “FizzBuzz”.

不過這篇由tickletux發表的個人牢騷像野火一般燒遍了國外的programmer blog,讓FizzBuzz聲名大噪了一番,
那篇講的主要其實也只是在抱怨他找的Programmer人選連解決像FizzBuzz的簡單問題都沒辦法,
不過這抱怨也激盪了出不少網路上最不缺的戰火話題跟創意,
以至於目前不少blog將FizzBuzz議題發表視為一種時尚.
(比如本blog接下來要做的事 :P)

基於傳教士的天性, 及追隨時尚盲從潮流的一種特殊快感,
篤信寫Python得永生的我也不得不特地趕上風潮:


def fizzbuzz(n,x):
"""tim like buzz, you like tim, so you get my dear john letter"""
if n == 100: return x + "Buzz"
elif not n % 15 : x += "FizzBuzz"
elif not n % 5 : x += "Buzz"
elif not n % 3 : x += "Fizz"
else: x += str(n)
return fizzbuzz(n+1,x)

print fizzbuzz(1,"")


嗯嗯 我的版本有沒有一種"為賦新詞強遞迴"的感覺? XD

還沒有嗎? 那是因為我寫的爛的緣故, 那後面這篇

"Ruby interpreting Prolog' interpreting Lisp interpreting Lisp solving FizzBuzz"

你就不得不"欣賞欣賞"了 :P

好好一個FizzBuzz又被他老兄離題到這種程度...

這又再度證明了一件我長久以來悟出比"FizzBuzz實驗"更加有說服力的結論:

"Programmer永遠能在極端無用的事物上才華洋溢"

(只是隨口說說啦... 如果有對結論已經認真起來的同學請仔細閱讀本blog右下角特別聲明 XD
好了好了 我啥都沒說 沒事多喝水多喝水.....orz)

星期四, 3月 01, 2007

stupidity driven testing

"""I don’t do test driven development. I do stupidity driven testing... I wait until I do something stupid, and then write tests to avoid doing it again.

— Titus Brown"""


Python有很多testing的工具,
包括內建的unittest/doctest,
3rd party的py.test/nose,
web application也可用twill,Selenium等特殊工具.
django目前的svn也有內建testing工具.
所以其實工具並不是什麼大問題.反而真正的重點是:

何時要testing? 要testing到什麼程度?

我在kalug有一次介紹python模組的時候有講過py.test,
曾聽過snowwolf在kalug介紹GUI testing(JUnit and Swing testing)
我也用過很pythonic的doctest,nose, 也用過django的testing模組(with unittest),
但是儘管對於工具本身並不陌生,
卻對於所謂的test-driven development這個概念還是覺得過於理想化,
因為能做的testing永遠覺得不夠, 到底一個項目要testing多少個Case?
到底要testing到何種程度才算完整才算足夠?
如果什麼都測我要什麼時候才開始真的寫code跟除錯?

Titus Brown在pycon2007的一語驚醒我這個夢中人:

古語有云: 知錯能改 善莫大焉!

一旦你coding時犯了一次錯,就把他寫成一個testing case!

testing不是要讓你不犯錯, 而是要避免你一錯再錯!

星期一, 2月 26, 2007

今年七月 Python3.0a1 發表 ?!

http://mail.python.org/pipermail/python-dev/2007-February/071375.html

看來這次似乎是認真的, 準備一口氣把GvR感覺不pythonic的東西全拿掉了.

這次語法淨化一次到位果然是大手筆:
照py3k的規劃, print 改成function,
map(),reduce(),filter()全移了.
xrange() raw_input() apply()也不見了.
operator / 不再是c的整數除法 改成浮點數運算了,
classic class消失了...
blahblah還有很多請自行參考http://www.python.org/dev/peps/pep-3100/

似乎由於不向後相容的關係, 這次會發表python2升3語法的工具,
不過還是沒想到今年的年中就會發表第一個alpha版,
之前GvR不是還在抱怨py3k沒人理嗎? =.=

明年就會有3.0final.... 這實在來的太快了 =)
話說這不少linux distribution都還停在python2.4啊...
總而言之, 這語法改變的適應期也還不算太短, 就慢慢來吧.

星期一, 2月 19, 2007

[link] PyPy 0.99.0 released !

http://codespeak.net/pypy/dist/pypy/doc/news.html

光看這個版本號就非常令人興奮. 沒想到1.0指日可待了 :)

PyPy一直是我非常關注的專案,
作者群裡面包含了Psyco的作者跟不少很有經驗的開發者,
加上有金主奧援, 可以看作是Scripting Language的指標專案之一.

專案的目標主要是用python來撰寫Python Interpreter,
PyPy的實作相對於其他如Cpython/Jython/Ironpython的好處是:

1. 讓Interpreter核心程式碼更容易懂:
使用Python而非傳統使用C或C++或java或C#

2.更容易移植
PyPy基本上顛覆了傳統撰寫Interpreter的方式,
PyPy並不是對特定平台而寫,而是寫出來之後低階與機器相關的部份透過"language specification"來翻譯.
所以實際上Interpreter的核心不論在哪個平台其實程式碼都是一樣的.
只有低階的部分由rpython撰寫並透過不同的翻譯器翻譯成目標平台的語言.

目前的svn code裡面的平台翻譯器有C/Java/.net/Common Lisp/Java script/squeak(small talk)/llvm. (翻成Javascript倒是挺有趣的, 這裡還示範了怎麼用pypy在django裡作ajax =.= 不過這麼前衛然後再加一層的技術目前我是不敢真的用在專案上的 除非pypy1.0之後有很多人採用 不然暫時我還是喜歡乖乖的寫我的javascript :P 不過有興趣而且不喜歡javascript的人倒是可以看這篇Developing web applications with PyPy)

3.更容易加入JIT compiler
官方宣稱透過"language specification"的方式可以作到傳統Interpreter作不到的事情,
例如替Interpreter加入JIT compiler,讓Interpreter也能達到接近native language的速度.
不過0.99版由於JIT尚未整合進Pypy核心, 所以還未放入,
所以實在是不知道未來PyPy到底能多快. (我對這個一向是抱持著看到才相信的態度 :P)
不過當初的秘密謠言(Rumors have it that the secret goal is being faster-than-C which is nonsense, isn't it?)...
對比現在的0.99版官方宣稱的overall 2-3 slower than CPython實在是無法令人滿意...
最主要是JIT的速度不如預期, 所以只能說請PyPy Team裡的高手多加加油了...

也希望快點有1.0出來囉也希望1.0文件多一點...
現在的文件數目對於我這種只是看著code流口水的EndUser來說實在是有點太少而且編排太亂...

ps: 剛看到reddit上也有人在討論 看起來像是rpython的使用範例.
範例中透過translatorshell.py翻譯Rpython成為C code可以比原先的pure python code快了70倍.
http://programming.reddit.com/info/152lr/comments/c156v0

星期日, 2月 18, 2007

[link] The Aha! point for lisp.

Aha! While writing YAQL I accidentally discovered Lisp

Greg Trasuk's Weblog:
"""
And then the AHA! moment happens. I finally "get" Lisp! It's just a string representation of the abstract syntax tree for any language! I could embed a Lisp interpreter in the query parser! I could use Lisp macros to perform optimizations on the query! There's a JJTree grammar for Python in the Jython package, I could parse Python into Lisp programs! I'm onto a Really Big Concept! Possibly the Next Big Thing, the grand unification of all scripting languages! Now I have to move back to Xemacs from Netbeans! All I need to do is increase the output by 15% and the city will be mine! If only I had More Power!
"""

話說自從lloyd大大傳授我他壓箱(真的是壓了好多層箱)
的Emacs Lisp聖書三大本,
最近寫Emacs Lisp寫出興趣來了,
發現其實Lisp很好玩,
以前雖然也沒事會裝裝武林高手,
用用lambda,map,filter...blahblah...
雖然把Code寫成一副很有"尊嚴"的樣子,
但是其實心裡總是覺得夾在Python的Code裡面就怪怪的,
多寫幾個就覺得很醜... 所以其實也只是偶而拿來減少一下loop需求而已.
但是, 果然玩了Lisp之後才知道人家是正牌的... XD

所以最近沒事都在讀讀Practical Common Lisp跟玩玩Emacs,
(不過最常幹的還是看動畫念日文跟網路亂逛), 然後看到這篇其實寫的很不錯.

他沒講到的話 我還真的不知道... 覺得這篇很有啟發性...
把任何語言的AST寫成字串形式其實就是LISP...(筆記筆記)
1958年就應該要知道的東西...
結果總是有人(就是我們這代人)在重造輪子...
算了, 反正造輪子總是比較爽... 自產自銷 XD

不過還是要說... 拜Python教的大家絕對不用氣餒...
Python+Django是無敵的...
(ㄟ lloyd大大...你又可以演吐槽角色了...)

星期六, 2月 17, 2007

lython approach 1.0 !?

繼不久前很久沒放出新版本的jython 放出了第一個2.2 beta之後,
lython突然也放出了 1.0版本,
原來是近期多了一位熱血開發者faulkner,
玩了一下發現很不賴, 可以使用CPython的Library啊!!!
排除了Not Enough Library這個問題之後,
Lisp就是非常非常吸引人的程式語言.

lython可以使用Lisp語法/Macro加上Python的Library,
而且仍然是產生.pyc ,
所以即使沒裝lython只要有CPython還是可以跑, 實在是很不錯.
希望faulkner再接再厲,
這樣的話就輪到有人寫一篇 Why lython is an acceptable LISP 的時候了. XD

lython內附的Example之一:


file-hello-world.lth
(import os)

(:= out "/tmp/lythontest")
(if (os.path.exists out)
(os.unlink out)
(print "target file does not exist"))

(:= f (open "/tmp/lythontest" "w+"))
(f.write "Hello World from Lython!\n")
(print "write you a letter in /tmp/lythontest")
(f.close)


Lython的interactive interpreter也學python學的很像:

-bash-3.00$ lython.py
Lython (experimental)
Type "(help)" if you need it.
Ly> (for x (range 10) (print x))
0
1
2
3
4
5
6
7
8
9

星期五, 2月 16, 2007

[link]Programming Language Stories

http://weblog.raganwald.com/2007/02/programming-language-stories.html

這篇好笑(難笑?!)的文章唯一跟Python有關的部份是跟使徒聖彼得對話的這段:

*****RoR閃光開始*****

Peter: “Welcome to heaven. Programming language?
聖彼得: 歡迎來到天堂. 用的程式語言?

Person #3: “Python.”
丙兄(前面Smalltalk跟Common Lisp的人都通過了): Python

Peter: “Room 54. Be very quiet as you pass Room Six.”
聖彼得: 五十四號房. 當你經過六號房時要很安靜的通過.

Person #3: “Why do you keep telling us to be quiet as we pass Room Six?”
丙兄:為甚麼你持續的跟我們說要很安靜的通過六號房?

Peter: “Because the Ruby on Rails People are in Room Six, and they think they’re the only ones here.”
聖彼得: 因為RoR那群人在六號房. 他們認為只有他們在這裡.

*****RoR 閃光完畢*****

但我覺得其實最好笑的是Scheme的部份, 好笑在哪裡?

哎呀, 其實是很難笑啦... 特別是你認真的從頭看到尾之後...

星期四, 2月 15, 2007

Bash-like Tab Completion in Emacs python-mode

Just hacked a bit, and a bash-like tab-completion in emacs python-mode is done. :)

Thanks Yuan Liu's tip and my friend lloyd's advices and tests,
also pymacs and python-mode developers,

it works quite well for tab completion using just tab key in python-mode.

1. install python-mode and pymacs

2. change /usr/share/emacs/site-lisp/python-mode/pycomplete.el to:


;;; Complete symbols at point using Pymacs.
;;; See pycomplete.py for the Python side of things and a short description
;;; of what to expect.

(require 'pymacs)
(require 'python-mode)

(pymacs-load "pycomplete")

;;check if prev character is blank-type
(defun char-before-blank ()
(save-excursion
(forward-char -1)
(looking-at "[\n\t\r]")))

(defun py-complete ()
(interactive)
(let ((pymacs-forget-mutability t))
(if (and
(and (eolp) (not (bolp))
(not (char-before-blank))))
(insert (pycomplete-pycomplete (py-symbol-near-point) (py-find-global-imports)))
(indent-for-tab-command))))

(defun py-find-global-imports ()
(save-excursion
(let (first-class-or-def imports)
(goto-char (point-min))
(setq first-class-or-def
(re-search-forward "^ *\\(def\\|class\\) " nil t))
(goto-char (point-min))
(setq imports nil)
(while (re-search-forward
"\\(import \\|from \\([A-Za-z_][A-Za-z_0-9\\.]*\\) import \\).*"
nil t)
(setq imports (append imports
(list (buffer-substring
(match-beginning 0)
(match-end 0))))))
imports)))

(define-key py-mode-map "\M-\C-i" 'py-complete)
(define-key py-mode-map "\t" 'py-complete)

(provide 'pycomplete)


3. change /usr/lib/python2.4/site-packages/pycomplete.py to:
(change your python path if different python version)

"""
Python dot expression completion using Pymacs.

This almost certainly needs work, but if you add

(require 'pycomplete)

to your .xemacs/init.el file (.emacs for GNU Emacs) and have Pymacs
installed, when you hit TAB it will try to complete the dot expression
before point. For example, given this import at the top of the file:

import time

typing "time.cl" then hitting TAB should complete "time.clock".

See pycomplete.el for the Emacs Lisp side of things.
"""
import sys
import os.path
import string
from Pymacs import lisp

sys.path.append(".")

try:
x = set
except NameError:
from sets import Set as set
else:
del x

def get_all_completions(s, imports=None):
"""Return contextual completion of s (string of >= zero chars).

If given, imports is a list of import statements to be executed first.
"""
locald = {}
if imports is not None:
for stmt in imports:
try:
exec stmt in globals(), locald
except TypeError:
raise TypeError, "invalid type: %s" % stmt
except:
continue
dots = s.split(".")
if not s or len(dots) == 1:
keys = set()
keys.update(locald.keys())
keys.update(globals().keys())
import __builtin__
keys.update(dir(__builtin__))
keys = list(keys)
keys.sort()
if s:
return [k for k in keys if k.startswith(s)]
else:
return keys

sym = None
for i in range(1, len(dots)):
s = ".".join(dots[:i])
try:
sym = eval(s, globals(), locald)
except NameError:
try:
sym = __import__(s, globals(), locald, [])
except ImportError:
return []
if sym is not None:
s = dots[-1]
return [k for k in dir(sym) if k.startswith(s)]

def pycomplete(s, imports=None):
completions = get_all_completions(s, imports)
dots = s.split(".")
result = os.path.commonprefix([k[len(dots[-1]):] for k in completions])

if result == "":
if completions:
width = lisp.window_width() - 2
colum = width / 20
white = " "

msg = ""

counter = 0
for completion in completions :
if completion.__len__() < 20 :
msg += completion + white[completion.__len__():]
counter += 1
else :
msg += completion + white[completion.__len__() - 20:]
counter += 2

if counter >= colum :
counter = 0
msg += '\n'

else:
msg = "no completions!"
lisp.message(msg)
return result

if __name__ == "__main__":
print " ->", pycomplete("")
print "sys.get ->", pycomplete("sys.get")
print "sy ->", pycomplete("sy")
print "sy (sys in context) ->", pycomplete("sy", imports=["import sys"])
print "foo. ->", pycomplete("foo.")
print "Enc (email * imported) ->",
print pycomplete("Enc", imports=["from email import *"])
print "E (email * imported) ->",
print pycomplete("E", imports=["from email import *"])

print "Enc ->", pycomplete("Enc")
print "E ->", pycomplete("E")

# Local Variables :
# pymacs-auto-reload : t
# End :


4. add this line into your .emacs
(require 'pycomplete)

That's it!

ps: you can also grab pycomplete.el and pycomplete.py here

ps2: if you install python-mode and pymacs from scratch,
don't forget add these lines in your .emacs:

(add-to-list 'load-path "/usr/share/emacs/site-lisp/python-mode")

(autoload 'python-mode "python-mode" "Python editing mode." t)
(autoload 'jython-mode "python-mode" "Python editing mode." t)
(autoload 'py-shell "python-mode" "Start an interactive Python interpreter in another window." t)
(autoload 'doctest-mode "doctest-mode" "Editing mode for Python Doctest examples." t)
(autoload 'py-complete "pycomplete" "Complete a symbol at point using Pymacs." t)

(add-to-list 'auto-mode-alist '("\\.py$" . python-mode))
(add-to-list 'auto-mode-alist '("\\.doctest$" . doctest-mode))

(add-to-list 'interpreter-mode-alist '("python" . python-mode))
(add-to-list 'interpreter-mode-alist '("jython" . jython-mode))

(add-to-list 'load-path "/usr/share/emacs/site-lisp/pymacs")

(autoload 'pymacs-load "pymacs" nil t)
(autoload 'pymacs-eval "pymacs" nil t)
(autoload 'pymacs-apply "pymacs")
(autoload 'pymacs-call "pymacs")

星期日, 2月 11, 2007

ezpyinline 0.1 釋出

http://cheeseshop.python.org/pypi/ezpyinline

ezpyinline是我想改進已經從2001年就沒釋出新版的PyInline的一個新專案.
目的就是想讓Python底下非常容易內嵌C語言來改善速度.

我知道類似的東西很多,
std裡的dl,ctypes, 3-party的pyrex,Boost.python,weave,shedskin等很多...
都是為了改善Python的速度.
但是可沒有一個有作到這麼簡單使用,
讓使用者只需下載一個.py檔案就完成一切.使用者也不需自行編譯C.

因此我覺得ezpyinline特別適合用來評估你的Python程式,
到底哪一部份和有沒有必要使用C改寫.

而ezpyinline的精神基本上就是希望完全不用作任何設定.
第一次使用就自動幫妳編譯, 所有編譯出來的檔案也自動幫妳管理.
使用者只要寫Code, 所有系統維護的事都不用煩惱.

講這麼多都沒用, 試一下就知道了, when you see it, you know it.

安裝:
力求做到無痛及輕量, 有setuptools的, 可以直接 easy_install -Z ezpyinline
沒有超級使用者權限或者不想安裝的使用者也可以下載完直接拷貝
ezpyinline.py到你想要內嵌script的目錄

使用:
安裝或下載完之後, 編輯helloworld.py

#!/usr/bin/python
import ezpyinline

code = r"""
int helloworld() {
printf("hello ezpyinline!\n");
}
"""

ezpyinline.C(code).helloworld()

儲存檔案, 執行python helloworld.py
hello ezpyinline!

嘿, it works :)

網站上有更多說明,
過一陣子我也會把東西跟文件寫詳細一點加到Sourceforge上.

ps:
恩, 不要誤會了,
我可不是鼓勵使用者使用C,

老生常談的"premature optimization is the root of all evil",


Optimization: Your Worst Enemy 也指出
Do not do clever optimizations that have no meaning.

但不得不承認C在某些特定應用目前無人可敵,
在軟體的進程尚未發展到能拋棄C的使用時, (或許數十年之內也不會有)
使用Python, "偶而"加上部分的C是可以被我這種Python基本教義派"原諒"的. :P
既然如此, 何不作的更容易使用?