2015/06/26

QAs for Python Beginners

學習 Python 前,你可能會遇到下列的疑問,對於這些問題,你心裡的答案是什麼呢?

這裡未必提供完整精準的解析,但希望有助於帶你看到學習程式語言的新觀點。

要懂物件導向才能學習 Python 嗎?

在 Python 中,每個東西都是物件,但,不代表你必須使用物件導向作為 Python 的主要典範,舉例來說,有人仿照 Functional Programming 典範來使用 Python。不懂物件導向觀念,不致於成為學習的阻礙,當然,具備物件導向的觀念,有助於進階議題的學習。

Python 是 Script 語言,執行效率一定比較慢囉?

善用內建函式和內建型別的情況下,Python 的效能並沒有比編譯式語言來得差。常見的建議是,等到程式架構穩定之後,再決定是否要處理效能問題,以及採取怎樣的處理方式。參考下列文件:

  • http://www.python.org/doc/essays/comparisons/
  • http://www.infoworld.com/article/2619428/python/van-rossum--python-is-not-too-slow.html
  • http://www.monitis.com/blog/2012/02/13/python-performance-tips-part-1

Python 的中文書籍很少,需要具備足夠英文程度才能學習嗎?

編寫品質良好的中文程式書籍,是極度吃力不討好的工作,結果就是,我們在市面上很難找到好的中文書。英文書的種類和數量,相對就多些。 想要自學的朋友,先選擇好的英文書和線上文件外,聰明的作法,就是參加同好聚會,線上和實體課程。

需要選好 IDE 才能開始 Python 編程嗎?

Python 世界裡存在許多 IDE 編輯器,免費或付費版本都有,各有愛用者。不少人使用 Vim 或 Sublime Text 就覺得夠用,所以,沒有 IDE 無法編程,對 Python 肯定是不成立的。

Python 的變數不用事先宣告型態,容易造成程式產生難以預期的錯誤或漏洞?

Python 是 Dynamic Typing 語言,使用變數時,不像 C 或 Java 需要事先宣告資料型態。Python 雖然有 Private 變數,但不像一般程式語言那樣具有強制力。通常會利用 Testing 來降低資料型態不明可能造成的問題,另一方面,也利用 Duck Typing 特性來避免資料型態檢查的需要。

2015/05/25

Learning Programming Fast

絕不貪快,按部就班,是學好程式的不二法門,除此之外,還是有五個步驟,有助加速學習:

  1. 先讀範例程式,再讀說明文字。
  2. 打一遍範例程式,執行並測試。
  3. 找個實例練習自己寫程式。
  4. 學習使用除錯器。
  5. 聰明發問,獲得更多角度的解說。

以上我稱之為「程式學習快速秘笈」,原文在這裡。

2015/05/22

After-School Class

小孩的媽,最近開始比較住家附近的安親班,用心程度,堪比孟母三遷。

藉由這些親身接觸的機會,我們才體會現代孟母面對怎樣的挑戰。

首先,安親班數量之多,約是便利商店三倍;其次,從業者專注特色,幾近苛求。

有哪些特色呢? 九成會強調純美語、或雙語教學,如果之前沒有足夠的美語根基,要嘛入班前加強訓練,跟上進度,要嘛就不必進去啦,意思是不要拉下既有班級的素質。至於沒有美語課程的安親班,數量雖少,但氣勢也不輸人,強調「省下來」的時間,會加強學生的在校功課,還有戶外運動。

有一家強調網站軟體,小孩回家可以線上複習,「那麼,該怎樣知道小孩有沒有乖乖複習呢?」「我們有會員系統,可以知道誰有沒有登入看影片。」我腦袋浮出的畫面是,哪一天,小朋友們都會安裝好自動登入的外掛程式吧。

總歸一句話,別讓孩子輸在起跑點。但,我依舊納悶,目標在哪個方向都不知道,起跑再早有什麼意義呢?

2015/02/09

Plone Widgets

Shelagh Delaney on the cover of Encore, source: http://jadorepop.rumblr.com/

Plone 5 使用 Mockup 做為前端函式庫,目的是讓 Plone 的 Javascript 開發更容易與外界成果結合,像 plone.app.widgets 就是範例成果,它可以取代舊的 Widget 程式,從技術的角度來看,代表我們不必再依賴 z3c.form 來建立 Widget 程式碼。截圖畫面和相關細節,可參考簡報介紹。

如果有任何原因,讓你無法直接使用 Plone 5 環境,從 Plone 4.3.4 Installer 起頭,也能方便地啟用 plone.app.widgets,我的方法和步驟如下:

$ vi develop.cfg
[sources]
plone.app.event = git git@github.com:plone/plone.app.event.git branch=1.2.x
plone.app.contenttypes = git git@github.com:plone/plone.app.contenttypes.git branch=1.1.x

[buildout]
eggs +=
    plone.app.widgets [dexterity]
    plone.app.contenttypes

zcml +=
    plone.app.widgets

$ vi versions.cfg
plone.app.jquery = 1.8.3

$ bin/buildout -c develop.cfg
# will stop by the error:  There is a version conflict. We already have: plone.app.event 1.1.4

$ vi src/plone.app.contenttypes/setup.py
'plone.app.event [dexterity]' # remove <1.1.999

上述過程適用於全新站台的建立,如果舊站昇級的話,可能會遇到 Tags 欄位未被昇級的狀況。

2014/12/26

Chinese Language Formula

中文在數位世界裡,理想上的處理方式,認真探討的人很少,實作的累積速度也慢,不過,這份資源值得參考: http://chineselanguageformula.sourceforge.net/

中文語言方程,以構字式為基礎,針對所有的 ISO 639-3 及民族語,採取語言學的正規方法,進行統一處理。目前多組相關的程式碼公開釋出後,原作者想要找人接手維護。

2014/08/14

Diazo Beginner Steps

累積 Diazo 的歷史和原理後,最近終於有個小案子能具體實戰。值得注意的是,套用 Diazo 時,並沒有存在特定的標準解法,需要搭配情境和資源現況,再決定從 Theme 或 Content 或 Rule 找到最容易下手的平衡點。

Theme 原始檔是從 ThemeForest 購買,樣版大致分成「首頁」「列表」「個別頁面」三大類,對初學者容易上手的步驟,是先修改首頁 HTML 符合自己的需要,再編寫 Rule 套用首頁的 Theme 和 Content,接著再逐步納入列表和個別頁面的樣版。編寫 Rule 的過程中,需要仔細比對 Content 和 Theme 的 HTML Tag 或是 XPath,為了方便比對,開啟兩個 browser 畫面,利用 Alt + Tab 切換。有個小撇步,在網址後面加上 ?diazo.off=1 就能暫時取消 Diazo 的效果,但在開發階段,全站式的取消效果會更方便。

以 http://diazo.mysite.com/ 為例,如果 Plone Site 在 http://168.168.168.168:8080/drchen 執行,可以在 http://168.168.168.168:8080/drchen/@@theming-controlpanel 指定 168.168.168.168 是「不套用佈景主題的網址」,這樣就可以在 http://diazo.mysite.com/ 顯示 Rule 生效後的結果,在 http://168.168.168.168:8080/drchen 顯示 Untheme Content 的結果。

網址的對應,是 Diazo Rule 最常見的設定工作之一。以下列 Theme 程式碼為例:

<a href="index.html">
<img src="img/logo.png" />
MySite Home</a>

它會被預設轉換成:

<a href="/++theme++drchen.theme/index.html">
<img src="/++theme++drchen.theme/img/logo.png" />
MySite Home</a>

對於圖檔而言,這樣的網址轉換並沒有造成困擾,但是 A Tag 就得額外處理。最直覺的方式,是讀取 Content 實際的 href 屬性值來取代,有趣的是,雖然是要「取代」 Link 值,但 Rule 語法要用 <copy /> 並指定 Attribute,用 XPath 選取 Node 的範例長得像這樣:

<copy attributes="href"
           theme="/html/body/div[2]/div[1]/div/div[1]/a"
         content="//*[@id='portal-logo']" />

我的理解是,想要取代 Node 時,才用 <replace />。接著,我們以 Global Section 為例,介紹幾個相關的對應情境。

想要逐一取代 Global Section 的 A Tag,我們可以仿照上述技巧,透過下列的範例語法來達成:

<replace theme="/html/body/div[2]/div[1]/div/ul/li[1]/a"
       content="//*[@id='portaltab-index_html']/a" />

不過,在這個例子裡,我們應該要連帶處理 <li class="selected"> 的部份,僅是取代 A Tag 的結果並未滿足實際的需要。那麼,取代整個 <ul /> 如何? 事實上,我們想留下 Theme 的 <ul> 但取代掉剩下的 <li /> 部份。幸好,有個 -children 語法能夠漂亮地處理這種需求:

<replace theme-children="/html/body/div[2]/div[1]/div/ul"
      content-children="//*[@id='portal-globalnav']" />

我有成功試過其他方法,是先修改 Global Section Viewlet 的 Template 內容,在 <ul> 加上 CSS Class 屬性值,再用 <replace /> 完成取代。相較之下,簡潔的 -children 語法就像一刀斃命。

有時候會遇到一個 Node 裡,同時有數個 A Tag 要指向相關的網址,參考下列的 Theme 原始碼:

<li>
<h2>
<a href="#" title="">
看診科別項目
</a>
</h2>
<div class="news clearfix">
<p class="text">
小兒科、過敏氣喘、耳鼻喉治療<br>
內科、慢性病處方簽<br>
成人、小兒感冒 等
</p>
<a href="#" title="">更多說明</a>
</div>
</li>

利用 //a 的 XPath 語法,可以指定 Node 裡的所有 A Tag,參考下列的 Rule 範例:

<copy attributes="href"
         theme="/html/body/div[2]/div[2]/ul/li[1]//a"
       content="//*[@id='portletwrapper-ID']/dl/dt/span[2]/a" />