高見龍

iOS app/Ruby/Rails Developer & Instructor, 喜愛非主流的新玩具 :)

安裝Python

不管你用的Linux/FreeBSD/MacOS/Windows..etc,目前Python均有實作品,請至http://python.org/getit/找到適合的平台並下載安裝。

不過,我不得小小抱怨一下,Python在Windows上實在是不怎麼友善,包括我們之後要講的Django,原本也有給Windows的懶人安裝包(Instant Django),但專案似乎也斷頭了。不過也不是沒有解決方法,如果只是要在Windows做練習的話,可參考下一章

如果你安裝完成,請打開你的終端機視窗,輸入python就可以進入interactive shell來試玩一下:

> python
Python 2.6.1 (r261:67515, Jun 24 2010, 21:47:49)
[GCC 4.2.1 (Apple Inc. build 5646)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> "hello python"
'hello python'
>>> 1 + 2
3

在這個shell裡面,你可以很容易的就測試一些簡單的程式碼,看看執行結果是不是跟你想像的是一樣的。有趣的是,如果你在shell裡輸入import this的話:

>>> import this
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!

你可以看到Tim Peters寫的The Zen of Python,內文大概說明了Python世界的設計哲學。至於import是做什麼用的,我們在後面的單元會再做說明。

除了shell之外,我們更常把程式碼儲存成一個檔案,附檔名是.py,例如我們把下面這段很簡單的程式碼:

1
2
#!/usr/bin/python
print "Hello, Python"

用任何文字編輯器打完之後,存檔為hello.py,然後回到終端機視窗,輸入python hello.py

> python test.py
Hello, Python

每種程式語言一定都要不免俗的來一下Hello World打個招呼的,如果在Java,你可能為了要輸出一行簡單的字,還得寫個類別或方法才行,在Python,只要一行print就搞定了,相當簡單吧 :)

其實老是Hello World也沒什麼意義,接下來我們來看一點稍微複雜一點的..

Python簡介

What is Python?

Python的老爸是,Guido van Rossum,聽說是他在1989年的時候的某個聖誕節無聊,然後就設計出這套程式語言,1991年放出來給大家用,到目前已經有將近20年的歷史了。

目前主流的版本是2.x跟3.x系列,最新的版本目前分別是2.7.2版及3.2.2版,但2.x跟3.x有不少地方是不相容的,各位在使用時還請多留意。

設計哲學

the Zen of Python裡提到了Python的設計哲學:

There should be one-- and preferably only one --obvious way to do it.

這與其它程式語言例如Perl的"There is more than one way to do it"是完全不同的。

What can Python do?

Python是一種物件導向的語言,雖然它被歸類到scripting language一族,但它能做的事情跟一般的程式語言一樣,從數學運算、系統管理到網站開發,它都做得來的,而且都還做得不錯。

有人會覺得嫌Python很慢,老實說,我是不覺得慢到哪裡去。當然拿它跟編譯型的程式語言比當然不公平,不過也就是因為它不用編譯,而且語法很好學好寫,開發速度相對的會比編譯型的語言要來得高。

Who is using Python?

  • Google
  • Youtube
  • NASA
  • ..and ME!

Why Python?

每種程式語言都有它的優缺點,以下是我個人覺得我喜歡Python的一些特點:

程式碼強制縮排

在Python寫程式,程式碼強制一定要縮排,長得像這樣:

say hello
1
2
3
def say_hello():
  print "Hello Python"
  print "Hello again!"

像這樣,不管你是要用tab或空白(space)都可以,要縮2格或4格都ok,只要對齊就行了。只要程式碼沒有對齊,在執行的時候就會直接出現IndentationError的錯誤訊息而無法繼續執行。

也許有些人不喜歡這種被強制規定的感覺,不過我個人還滿喜歡的。在別的程式語言,有的人喜歡把大括號放在最後面,有人喜歡把大括號放下一行,像這樣:

大括號的位置
1
2
3
4
5
6
7
8
function type1(){
  // 把大括號放最後面
}

function type2()
{
  // 把大括號放下一行
}

這沒有誰好誰壞的問題,不過這個在Python就比較不會有這樣的困擾,也因為如此,即使你是接手別人的案子,基本上程式碼的長相也不會差太多。

而且我真的遇過程式碼不縮排或亂縮排的工程師..

支援多個平台

目前幾乎所有比較主流的平台上面都有支援了,也就是說你在Linux底下寫的程式,搬到Windows上也能執行。(當然前提是沒有用到一些系統特定的模組或method)

免費取得

不僅不用錢,而且連Python的原始碼都可以讓你帶回家研究。

開發工具易取得

其實寫Python不用什麼特別的開發工具,基本上只要是一般的文字編輯器就可以了。也有一些像PyDev這種為Python量身打造的IDE(Integrated Development Environment)也不錯用,不過我個人偏好純文字編輯器,例如Vi,至少開啟速度快,而且搭配一些好用的外掛,該有的功能都差不多該有了。

其它

電腦程式語言幾乎都是外國人的世界,你有想過用中文可以寫程式嗎? 有個叫做周蟒的專案做到了。這是用中文寫出來的Python程式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#!/usr/bin/env zhpy
# 檔名: if.py
數字 = 23
猜測 = 整數(輸入('輸入一個數字: '))
如果 猜測 == 數字:
    印出 '恭喜, 你猜對了.' # 一個新區塊的開始
    印出 '(但沒有獎品喔!)' # 新區塊的結束
假使 猜測 < 數字:
    印出 '錯了, 數字再大一點.' # 另一個區塊
    # 你可以在區塊中做任何想做的事 ...
否則:
    印出 '錯了, 數字再小一點.'
    # 只有在猜測 > 數字 的情況下才會跑到這個區塊來
印出 '結束'
# 最後一行語句和"如果..假使..否則"語句是無關的,
# 因為最後的'印出'這行在主區塊中出現,所以這行永遠會被執行.

好寫嗎? 這見人見智了,不過挺有趣的,有興趣的朋友可以玩看看 :)

How to Install Octopress on Heroku

為什麼使用Octopress

這個我想xdite的Why Octopress?寫得很清楚了,就不多做說明了。

安裝

請到Octopress的官網官網找下載點,或是到github上也找得到Octopress on github,如果懶得找,請打開你的終端機視窗,然後跟我這樣做:

> cd /tmp
> git clone git://github.com/imathis/octopress.git

第一步切換到/tmp只是個人喜好,你可以換成別的。進到下載的資料夾裡,安裝需要的gem:

> cd octopress
> bundle install

沒問題的話..

> rake install
## Copying classic theme into ./source and ./sass

再來..

> rake preview

就會在你本機開一個port 4000的web server起來,開瀏覽器起來輸入http://127.0.0.1:4000/可以看到畫面如下:

image

不過你會看到一些像是Blog title都是預設值,這些都是可以修改的,基本上修改都是在_config.yml這個檔案裡,相關設定請參考這裡

不難吧! 你已經完成一半的工作囉,接著我們來寫第一篇文章。

管理介面?

你是說像wordpress那種有個帳號密碼登入的管理介面嗎? 沒這種東西啦! Octopress的文章都是由markdown檔案轉成靜態html,寫完就丟上去,就這麼單純而已。

寫文章

在Octopress,每篇文章就是一個markdown檔,檔案需要放在source/_posts底下,並依照YYYY-MM-DD-post-title.markdown的格式來命名,例如我這篇的檔名就是2011-10-11-how-to-install-octopress.markdown,這樣待會在轉成靜態html的時候才會找得到。

以上這個動作你可以手動自己做,不過我會建議是透過rake指令幫你做:

> rake new_post[how-to-install-octopress]
Creating new post: source/_posts/2011-10-11-how-to-install-octopress.markdown

因為用rake幫你建立的markdown檔,會幫你加一些文章的表頭相關設定。不管你是手動還是rake自動產生的markdown檔,剩下的就是動手寫文章了。

另外,如果你的shell是用zsh的話,上面這個指令可能會讓你出現這樣的狀況:

>   zsh: no matches found: new_post[how-to-install-octopress]

如果遇到這個狀況的話,你可改一下你的.zshrc,加上這行:

alias rake="noglob rake"

或是改一下原來的rake指令:

> rake "new_post[how-to-install-octopress]"

怎麼寫?

就跟你平常寫文章一樣啦! 也許你會好奇,用markdown語法來寫文章真的方便嗎? 對我這種喜歡敲鍵盤而且又常需要在文章裡放程式碼的人來說還挺不錯用的。我是覺得只要習慣的話是還滿快的,markdown的語法要記的也沒多少,寫幾次大概就背起來了。事實上你正在看的這篇文章就是用markdown編寫的。

有推薦的編輯器嗎? 我覺得Mou挺不錯用的!

不會寫? 這裡有小抄可以參考。

寫好了,然後..?

markdown寫好之後,再來就是要把markdown轉成靜態html檔案了:

> rake generate
## Generating Site with Jekyll
unchanged sass/screen.scss
Configuration from /private/tmp/octopress/_config.yml
Building site: source -> public
Successfully generated site: source -> public

執行這個rake generate要注意的是,你可能會在你的文章裡會插入一些圖檔,請記得你的圖檔是放在source/images這個資料夾裡,而不是public/images,因為在做rake generate的時候會以source資料夾為主,並複製一份到public的相對應資料夾裡,如果你是直接把圖檔放在public裡,在比對的過程中就會被自動砍掉了。

在上傳之前

預設.gitignore會把public資料夾給忽略掉而不上傳,這個在一般的環境還ok,因為public資料夾裡的東西如果沒有的話會再自動重生,但因為我們準備把東西傳到Heroku,Heroku的檔案系統是唯讀的,不會讓你做這個動作,所以如果你也是要上傳到Heroku的,請記得修改這個檔案,把public給拿掉,不然你的轉好的內容都會傳不上去而出現Sorry, I cannot find /的錯誤訊息!

當初沒先看文件就亂玩,結果在這邊卡關卡超久..後來是翻heroku logs才發現原因,其實文件根本早就有寫了..orz

上傳到Heroku

因為待會我們要把東西丟上Heroku,所以請先上Heroku申請個帳號,Heroku的Getting Started with Heroku請先翻一下,相關gem也別忘了一起裝起來。

有帳號之後,用heroku來開個專案:

> heroku create happy-octopress
Creating happy-octopress... done, stack is bamboo-mri-1.9.2
http://happy-octopress.heroku.com/ | git@heroku.com:happy-octopress.git
Git remote heroku added

這個happy-octopress請改成你自己取的名字。再來就是把剛剛剛好的東西用git丟上去:

> git add .
> git commit -m 'first commit'
> git push heroku master
Counting objects: 3400, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (1218/1218), done.
Writing objects: 100% (3400/3400), 844.84 KiB, done.
Total 3400 (delta 1949), reused 3352 (delta 1916)

-----> Heroku receiving push
-----> Ruby/Sinatra app detected
-----> Gemfile detected, running Bundler version 1.0.7
       Unresolved dependencies detected; Installing...
       Using --without development:test
       Fetching source index for http://rubygems.org/
       Installing rack (1.3.2) 
       Installing tilt (1.3.2) 
       Installing sinatra (1.2.6) 
       Using bundler (1.0.7) 
       Your bundle is complete! It was installed into ./.bundle/gems/
-----> Compiled slug size is 608K
-----> Launching... done, v4
       http://happy-octopress.heroku.com deployed to Heroku

To git@heroku.com:happy-octopress.git
 * [new branch]      master -> master

就這樣,你可以自己打開瀏覽器,輸入網址http://happy-octopress.heroku.com,或是叫heroku幫你開:

> heroku open

沒意外的話,應該就可以看到架好的Octopress,以及你剛剛寫的文章了。

大概就是這樣,更多的說明請參考Octopress官網。若有任何問題或是有哪邊寫錯了,歡迎一起來討論囉 :)

Zoë – 從SWF匯出SpriteSheet的方便工具

前一篇簡單的介紹了一下EaselJS,其中有個類別叫做SpriteSheet,其實它就是把一些連續動作的圖片排排站的集合拼成一張圖,把檔案及相關的frame data包成SpriteSheet之後,再讓這些連續圖檔連續播放,感覺就會像動畫了。在之後的文章應該還會有更多關於SpriteSheet的說明,如果你還是沒辦法想像Spritesheet是怎麼回事,你可以回想一下設計師在Flash做動畫的時候,會在時間軸上安插一堆的關鍵影格(Key Frame),然後讓每個關鍵影格的動作都稍微有些變化,大概就是這樣的概念,只是HTML5並沒有時間軸可以用。

一個跑步的角色的SpriteSheet圖片可能會長這樣:

image

感謝Maso哥提供!

若你之前曾經用Flash做過些小遊戲,有些動態效果你已經做成MovieClip了,你當然可以打開繪圖軟體來一塊一塊的拼貼成SpriteSheet圖檔,然後還得自己寫frame data,這樣實在有些辛苦。有鑑於此,Grant Skinner大神用Adobe AIR寫了個叫做Zoë小工具,可以讓你很容易的把SWF裡的東西轉成SpriteSheet圖檔,而且還順便幫你產生一個給EaselJS用的frame data。(GS大神請受我一拜!)

安裝

請到Zoë的下載頁面下載相關檔案,再來解壓縮、安裝,應該沒什麼太大的難度。(Zoë是用Adobe AIR寫的,所以你的電腦也需要安裝AIR的runtime)

使用

打開安裝好的Zoë,然後把SWF拖進去,它會自動開始幫你算邊界(bound),或是你也可以自己切到Bounds功能按下Calculate按鈕:

image

再切到Export功能,勾選EaselJS,按下Export按鈕:

image

然後,你會得到一張拼好的png圖檔像這樣:

image

同時你還會得到一個同名的js檔,內容如下:

1
2
3
4
5
6
var frameData = {
  run:[0,4]
};
var img = new Image()
img.src = "hero.png"
var spriteSheet = new SpriteSheet(img,48,68,frameData);

如果你發現你的frameData裡面是空的,可能是因為你少了label關係,這是我在Flash IDE裡的樣子:

image

老實說這軟體沒什麼好介紹的,就是執行、匯出..就這樣。

用這樣轉檔有什麼好處? 首先,如果你之前有做好的動態,至少不用再手工拼貼連續圖。就算是從頭開始做,對設計師來說,在Flash使用關鍵影格來做動態也是很方便的(這是Flash的強項啊)。

動手寫code了

接下來,來試著讓這個SpriteSheet動起來!

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="Content-type" content="text/html; charset=utf-8">
  <title>SpriteSheet Demo</title>
  <script type="text/javascript" src="easel.js"></script>
  <style type="text/css" media="screen">
    #my_canvas{
      background-color: gray;
    }
  </style>
  <script type="text/javascript">
    var stage;

    function init()
    {
      var canvas = document.getElementById("my_canvas");
      stage = new Stage(canvas);

      var frameData = {
        run:[0,4]
      };
      var img = new Image()
      img.src = "hero.png";
      var spriteSheet = new SpriteSheet(img,48,68,frameData);

      var hero = new BitmapSequence(spriteSheet);
      hero.gotoAndPlay("run");

      stage.addChild(hero);
      stage.update();

      Ticker.setFPS(24);
      Ticker.addListener(this);
    }

    function tick()
    {
      stage.update();
    }
  </script>
</head>
<body onload="javascript:init();">
<canvas width="200" height="80" id="my_canvas"></canvas>
</body>
</html>

效果如下:

或按這裡檢視。

程式碼跟上一個範例沒有太大的差別,中間那段SpriteSheet的內容是從剛剛產出的同名js剪過來的。但SpriteSheet本身並不是DisplayObject的一種,所以需要來個BitmapSequence來把它包起來,然後執行閃客們都很熟悉的gotoAndPlay():

1
2
var hero = new BitmapSequence(spriteSheet);
hero.gotoAndPlay("run");

看吧,不用幾行程式碼就能讓帥氣的廖添丁動起來了!!

最後,要再感謝一下Maso哥提供的原始檔。至於會不會在不久的將來就會看到HTML5版的廖添丁呢.. 也許大家可以期待一下囉。